【问题标题】: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

标签: linux bash shell ssh


【解决方案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 的输出进行脚本逻辑绝不是一个好主意。它可能会根据您的帐户配置和其他注意事项而改变。
                  猜你喜欢
                  • 2016-07-29
                  • 1970-01-01
                  • 2010-10-25
                  • 2013-01-01
                  • 1970-01-01
                  • 2020-06-15
                  • 1970-01-01
                  • 2020-06-23
                  • 1970-01-01
                  相关资源
                  最近更新 更多