使用 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 服务器上的文件是不是存在

判断远程主机文件是不是存在

用shell判断远程主机上是否存在某个文件

要在一台主机上执行shell脚本判断另一台上的某个文件是不是存在,这个shell语句该怎么写?

SSH 远程执行任务