使用 ssh 检查远程主机上是不是存在文件
Posted
技术标签:
【中文标题】使用 ssh 检查远程主机上是不是存在文件【英文标题】:check if file exists on remote host with ssh使用 ssh 检查远程主机上是否存在文件 【发布时间】:2012-10-02 10:49:18 【问题描述】:我想检查远程主机上是否存在某个文件。 我试过这个:
$ if [ ssh user@localhost -p 19999 -e /home/user/Dropbox/path/Research_and_Development/Puffer_and_Traps/Repeaters_Network/UBC_LOGS/log1349544129.tar.bz2 ] then echo "okidoke"; else "not okay!" fi
-sh: syntax error: unexpected "else" (expecting "then")
【问题讨论】:
您正在尝试执行该文件... 一般情况下then
前需要一个分号:if cmd; then cmd; else cmd; fi
【参考方案1】:
除了上面的答案,还有一个简写的方法:
ssh -q $HOST [[ -f $FILE_PATH ]] && echo "File exists" || echo "File does not exist";
-q
是安静模式,它会抑制警告和消息。
正如@Mat 提到的,像这样测试的一个优点是您可以轻松地将-f
替换为您喜欢的任何测试运算符:-nt
、-d
、-s
等...
测试操作员: http://tldp.org/LDP/abs/html/fto.html
【讨论】:
+1,但这假设接收主机有 bash 并且它是用户的默认 shell。 我真的很喜欢你的解决方案。仅适用于像我这样的新生 if-else 版本: if ssh -q $HOST [[ -f $FILE_PATH ]] ;然后回显“文件存在”; else "找不到文件" ;菲 这太老了,但我需要帮助。这工作得很好,但我正在迭代几个文件,我需要在找到第一个文件时停止。我该怎么做?【参考方案2】:这是一个简单的方法:
#!/bin/bash
USE_IP='-o StrictHostKeyChecking=no username@192.168.1.2'
FILE_NAME=/home/user/file.txt
SSH_PASS='sshpass -p password-for-remote-machine'
if $SSH_PASS ssh $USE_IP stat $FILE_NAME \> /dev/null 2\>\&1
then
echo "File exists"
else
echo "File does not exist"
fi
您需要在您的机器上安装sshpass 才能使用它。
【讨论】:
如何反转if?if [ -n ... ]
?
如果你只使用test
而不是stat
会更好。 test
是 IEEE 标准。 stat
是非标准的。 test
不会在失败时输出消息,它只是返回一个标准的退出状态。
它可以工作,但需要$HOST
的登录名和密码。是否可以进行无密码身份验证,或者有没有办法在脚本本身中输入登录名和密码。谢谢
@Yash 在运行此脚本之前,您必须首先在本地计算机上生成 ssh 公钥/私钥对,yes 'y' | ssh-keygen -t rsa -f ~/.ssh/replace_me_with_a_keyname -N " "
然后通过公钥 scp 到远程计算机并添加本地机器到 known_hosts。 scp -o StrictHostKeyChecking=no ~/.ssh/replace_me_with_a_keyname.pub host_username@host_ip:~/.ssh/
。第一次运行时需要用户名和密码,但每次你 ssh 运行更多脚本时,它会自动使用密钥身份验证登录
这是否通过横幅进行了测试?【参考方案3】:
没有比这更简单的了 :)
ssh host "test -e /path/to/file"
if [ $? -eq 0 ]; then
# your file exists
fi
根据 dimo414 的建议,这可以折叠为:
if ssh host "test -e /path/to/file"; then
# your file exists
fi
【讨论】:
是的,它可以,你可以用ssh
命令本身替换[ $? -eq 0 ]
:)
@dimo414 你能更具体地谈谈你的建议吗?
@Dr_Zaszuś foo; if (( $? == 0 )); then ...; fi
等同于 if foo; then ...; fi
。很少需要使用$?
来检查命令是否成功。这是another answer,我在这里谈论这个。
这种情况下双引号也可以去掉。【参考方案4】:
一行,正确引用
ssh remote_host test -f "/path/to/file" && echo found || echo not found
【讨论】:
【参考方案5】:你错过了;
s。如果将它们全部放在一行中,一般语法是:
if thing ; then ... ; else ... ; fi
thing
几乎可以是任何返回退出代码的东西。如果thing
返回0,则采用then
分支,否则采用else
分支。
[
不是语法,它是 test
程序(查看 ls /bin/[
,它确实存在,man test
用于文档 - 尽管也可以具有具有不同/附加功能的内置版本。 ) 用于测试文件和变量的各种常见条件。 (请注意,另一方面,[[
是 是 语法,如果支持,则由您的 shell 处理)。
对于你的情况,你不想直接使用test
,你想在远程主机上测试一些东西。所以试试类似的东西:
if ssh user@host test -e "$file" ; then ... ; else ... ; fi
【讨论】:
它甚至不应该是if [
,而应该只是if ssh ...
。
非常正确,是在没有将它们联系在一起的情况下查看这两个问题。【参考方案6】:
ssh -q $HOST [[ -f $FILE_PATH ]] && echo "File exists"
上面将在您运行 ssh 命令的机器上运行 echo 命令。让远程服务器运行命令:
ssh -q $HOST "[[ ! -f $FILE_PATH ]] && touch $FILE_PATH"
【讨论】:
【参考方案7】:测试文件是否存在:
HOST="example.com"
FILE="/path/to/file"
if ssh $HOST "test -e $FILE"; then
echo "File exists."
else
echo "File does not exist."
fi
反之,测试文件是否不存在:
HOST="example.com"
FILE="/path/to/file"
if ! ssh $HOST "test -e $FILE"; then
echo "File does not exist."
else
echo "File exists."
fi
【讨论】:
【参考方案8】:您可以指定远程主机在本地使用的shell。
echo 'echo "Bash version: $BASH_VERSION"' | ssh -q localhost bash
并注意(单)引用您希望由远程主机扩展的变量;否则变量扩展将由您的本地 shell 完成!
# example for local / remote variable expansion
echo "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'" |
ssh -q localhost bash
echo '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"' |
ssh -q localhost bash
因此,要检查远程主机上是否存在某个文件,您可以执行以下操作:
host='localhost' # localhost as test case
file='~/.bash_history'
if `echo 'test -f '"$file"' && exit 0 || exit 1' | ssh -q "$host" sh`; then
#if `echo '[[ -f '"$file"' ]] && exit 0 || exit 1' | ssh -q "$host" bash`; then
echo exists
else
echo does not exist
fi
【讨论】:
【参考方案9】:静默检查文件是否存在,如果不存在则执行
if ! ssh $USER@$HOST "test -e file.txt" 2> /dev/null; then
echo "File not exist"
fi
【讨论】:
【参考方案10】:我还想检查远程文件是否存在但使用 RSH。我已经尝试过以前的解决方案,但它们不适用于 RSH。
最后,我做了简短的功能,效果很好:
function existRemoteFile ()
REMOTE=$1
FILE=$2
RESULT=$(rsh -l user $REMOTE "test -e $FILE && echo \"0\" || echo \"1\"")
if [ $RESULT -eq 0 ]
then
return 0
else
return 1
fi
【讨论】:
【参考方案11】:在 CentOS 机器上,对我有用的 oneliner bash 是:
if ssh <servername> "stat <filename> > /dev/null 2>&1"; then echo "file exists"; else echo "file doesnt exits"; fi
它需要 I/O 重定向(作为最佳答案)以及在远程运行的命令周围加上引号。
【讨论】:
【参考方案12】:这也有效:
if ssh user@ip "[ -s /path/file_name ]" ;then
status=RECEIVED ;
else
status=MISSING ;
fi
【讨论】:
【参考方案13】:#its simple
if [[ "`ssh -q user@hostname ls /dir/filename.abc 2>dev/null`" == "/dir/filename.abc" ]]
then
echo "file exists"
else
echo "file not exists"
fi
【讨论】:
依赖ls
的输出进行脚本逻辑绝不是一个好主意。它可能会根据您的帐户配置和其他注意事项而改变。以上是关于使用 ssh 检查远程主机上是不是存在文件的主要内容,如果未能解决你的问题,请参考以下文章
如果在没有 ssh-ing 的情况下不存在远程主机上的目录,如何在它上创建目录?
使用 Python 检查远程 SSH 服务器上的文件是不是存在