简体   繁体   English

通过ssh执行复杂命令时的语法错误

[英]Syntax errors when executing a complex command via ssh

I would like to know if a server is running and if not then i would like to start it. 我想知道服务器是否正在运行,如果没有,那么我想启动它。 for this scenario I have written the following bash script 对于这种情况,我编写了以下bash脚本

ssh -t machine "cd /to/the/bin/path 
  && if [ -n $(sudo -u dev ps U dev | grep server_name | awk 'FNR == 1 {print $1}') ] 
     then 
          echo 'podsvr is running with 
             id $(sudo -u dev ps U dev | grep POD | awk 'FNR == 1 {print $1}')' 
     else 
          sudo -u dev sfservice server_name start 
     fi
"

When I run the above program I am getting the following error 当我运行上述程序时,出现以下错误

bash: -c: line 1: syntax error: unexpected end of file bash:-c:第1行:语法错误:文件意外结束

Could some one please help me in this regards 有人可以在这方面帮助我吗

~Sunil 〜苏尼尔

You can't nest single quotes like that in bash. 您不能在bash中嵌套这样的单引号。 Change the second occurrence of: 更改第二次出现:

 'FNR == 1 {print $1}'

To: 至:

'\''FNR == 1 {print $1}'\''

Your quoting is messed up. 您的报价搞砸了。 Probably the main problem is that you put the entire ssh script in double quotes. 可能的主要问题是您将整个ssh脚本放在了双引号中。 Since it's included in double quotes, the $(...) parts are already evaluated on the local machine before the result is passed to the remote one, and the results are fairly nonsensical. 由于它包含在双引号中,因此$(...)部分已经在本地计算机上进行了评估,然后再将结果传递给远程计算机,并且结果相当荒谬。 I would use the following recipe: 我将使用以下配方:

  1. Write the script that should be executed on the remote machine. 编写应在远程计算机上执行的脚本。 Preferably log in to the remote machine and test it there. 最好登录到远程计算机并在那里进行测试。

  2. Now enclose the entire script in single quotes and replace every enclosed ' by '\\'' or alternatively by '"'"' . 现在,将整个脚本用引号引起来,并用'\\''或用'"'"'替换每个包含的'

  3. In case that the command contains a variable that should be evaluated on the local machine, put '\\'" in front of it and "\\'' after it. 在该命令包含应该在本地计算机上进行评估的变量情况下,把'\\'"在它的前面和"\\''之后。 For instance, if the command to be executed on the remote machine is 例如,如果要在远程计算机上执行的命令是

     foo "$A" "$B" 'some string' bar 

    but $B should be evaluated on the local machine, you get 但是应该在本地计算机上评估$B

     'foo "$A" '\\'"$B"\\'' '\\''some string'\\'' bar' 

    3.1 Note: This is not completely foolproof – it will fail if the string in $B contains ' . 3.1 注意:这不是绝对安全的方法-如果$B中的字符串包含' ,它将失败。 To be safe in cases where you cannot guarantee that there is no ' inside of $B , you can first execute QQ=\\'\\\\\\'\\' ; ProtectedB=${B//\\'/$QQ} 为了安全起见,在无法保证$B内没有'下,您可以先执行QQ=\\'\\\\\\'\\' ; ProtectedB=${B//\\'/$QQ} QQ=\\'\\\\\\'\\' ; ProtectedB=${B//\\'/$QQ} and then use '\\'"$ProtectedB"\\'' instead of '\\'"$B"\\'' in the command above. QQ=\\'\\\\\\'\\' ; ProtectedB=${B//\\'/$QQ} ,然后在上面的命令中使用'\\'"$ProtectedB"\\''而不是'\\'"$B"\\''

  4. Use the result as the argument of ssh. 将结果用作ssh的参数。

I assume that the following works (but I can't test it here). 我认为以下工作有效(但我无法在此处进行测试)。

ssh -t machine '
    cd /to/the/bin/path
    && if [ -n "$(sudo -u dev ps U dev | grep server_name | awk '\''FNR == 1 {print $1}'\'')" ]
       then
           echo "podsvr is running with id $(sudo -u dev ps U dev | grep POD | awk '\''FNR == 1 {print $1}'\'')"
       else
           sudo -u dev sfservice server_name start
       fi
'

There are a few things you can do to improve the command and simplify the quoting: 您可以做一些事情来改进命令并简化引用:

  1. There's no need to run ps using sudo to see processes running as another user. 无需使用sudo运行ps即可查看以其他用户身份运行的进程。
  2. Use the -q option to suppress the output of grep , and simply check the exit status to see if a match was found. 使用-q选项可抑制grep的输出,只需检查退出状态以查看是否找到匹配项。
  3. Use double-quotes with echo to allow the svc_id parameter to expand. 使用带有echo双引号可以扩展svc_id参数。
  4. Use single quotes around the entire command for the argument to ssh . ssh的参数在整个命令周围使用单引号。
  5. Presumably, /to/the/bin/path is where sfservice lives? 大概, /to/the/bin/pathsfservice You can probably just specify the full path to run the command, rather than changing the working directory. 您可能只需要指定运行命令的完整路径即可,而不用更改工作目录。

ssh -t machine 'if ps U dev -o command | grep -q -m1 server_name; then
                  svc_pid=$( ps U dev -o pid,command | grep -m1 POD | cut -d" " -f 1 )
                  echo "podsvr is running with id $svc_pid"
                else 
                  sudo -u dev /to/the/bin/path/sfservice server_name start 
                fi
'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM