Bash 通过ssh执行复杂命令时出现语法错误

Bash 通过ssh执行复杂命令时出现语法错误,bash,ssh,Bash,Ssh,我想知道服务器是否正在运行,如果没有,我想启动它。对于这个场景,我编写了以下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

我想知道服务器是否正在运行,如果没有,我想启动它。对于这个场景,我编写了以下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
"
当我运行上述程序时,我得到以下错误

bash:-c:第1行:语法错误:意外的文件结尾

有人能帮我这方面的忙吗


~Sunil

你不能在bash中嵌套这样的单引号。更改第二次出现的:

 'FNR == 1 {print $1}'
致:


不能在bash中嵌套这样的单引号。更改第二次出现的:

 'FNR == 1 {print $1}'
致:


你的报价搞砸了。可能主要的问题是您将整个ssh脚本放在双引号中。由于包含在双引号中,
$(…)
部分在将结果传递给远程计算机之前已经在本地计算机上进行了评估,并且结果相当荒谬。我会使用以下配方:

  • 编写应在远程计算机上执行的脚本。最好登录到远程机器并在那里进行测试

  • 现在,用单引号将整个脚本括起来,并用
    \'
    '
    替换每个
    '

  • 如果该命令包含一个应在本地计算机上计算的变量,请将
    '\'“
    放在它前面,将
    “\'
    放在它后面。例如,如果要在远程计算机上执行的命令是

    foo "$A" "$B" 'some string' bar
    
    但是,
    $B
    应该在本地计算机上进行计算,您会得到

    'foo "$A" '\'"$B"\'' '\''some string'\'' bar'
    
    3.1注意:这并不是完全可靠的–如果
    $B
    中的字符串包含
    ,则它将失败。为了在无法保证
    $B
    内部没有
    '
    的情况下确保安全,您可以首先执行
    QQ=\'\'\'\'\';ProtectedB=${B/\'/$QQ}
    然后在上面的命令中使用
    \''''''''''''''$ProtectedB'\'''
    而不是
    ''''''''$B'\'

  • 将结果用作ssh的参数

  • 我假设以下方法可行(但我不能在这里进行测试)


    你的报价搞砸了。可能主要的问题是您将整个ssh脚本放在双引号中。由于包含在双引号中,
    $(…)
    部分在将结果传递给远程计算机之前已经在本地计算机上进行了评估,并且结果相当荒谬。我会使用以下配方:

  • 编写应在远程计算机上执行的脚本。最好登录到远程机器并在那里进行测试

  • 现在,用单引号将整个脚本括起来,并用
    \'
    '
    替换每个
    '

  • 如果该命令包含一个应在本地计算机上计算的变量,请将
    '\'“
    放在它前面,将
    “\'
    放在它后面。例如,如果要在远程计算机上执行的命令是

    foo "$A" "$B" 'some string' bar
    
    但是,
    $B
    应该在本地计算机上进行计算,您会得到

    'foo "$A" '\'"$B"\'' '\''some string'\'' bar'
    
    3.1注意:这并不是完全可靠的–如果
    $B
    中的字符串包含
    ,则它将失败。为了在无法保证
    $B
    内部没有
    '
    的情况下确保安全,您可以首先执行
    QQ=\'\'\'\'\';ProtectedB=${B/\'/$QQ}
    然后在上面的命令中使用
    \''''''''''''''$ProtectedB'\'''
    而不是
    ''''''''$B'\'

  • 将结果用作ssh的参数

  • 我假设以下方法可行(但我不能在这里进行测试)


    您可以做一些事情来改进命令并简化引用:

  • 无需使用
    sudo
    运行
    ps
    来查看作为另一个用户运行的进程
  • 使用
    -q
    选项抑制
    grep
    的输出,只需检查退出状态 查看是否找到匹配项
  • 使用带有
    echo
    的双引号,以允许
    svc\u id
    参数展开
  • 对于
    ssh
    的参数,在整个命令周围使用单引号
  • 大概,
    /to/the/bin/path
    sfservice
    的所在地?您可能只需指定运行该命令的完整路径,而无需更改工作目录


  • 您可以做一些事情来改进命令并简化引用:

  • 无需使用
    sudo
    运行
    ps
    来查看作为另一个用户运行的进程
  • 使用
    -q
    选项抑制
    grep
    的输出,只需检查退出状态 查看是否找到匹配项
  • 使用带有
    echo
    的双引号,以允许
    svc\u id
    参数展开
  • 对于
    ssh
    的参数,在整个命令周围使用单引号
  • 大概,
    /to/the/bin/path
    sfservice
    的所在地?您可能只需指定运行该命令的完整路径,而无需更改工作目录


  • 我已经将脚本修改为ssh-t machine“cd/to/the/bin/path&&if[-n$(sudo-u dev ps u dev|grep server|u name | awk'FNR==1{print$1}')],然后echo'server|name正在以id$运行(sudo-u dev ps u dev|grep server|name | awk'''FNR==1{print$1}'''els sudo-u dev sfservice server| name启动fi现在我在查找匹配的`''test1.sh:line 1:unexpected EOF时遇到错误test1.sh:line 3:syntax error:unexpected end of fileTry在第一个
    $周围加上双引号(sudo-u dev ps u dev | grep server|u name | awk'FNR==1{print$1})
    同样如此。即使现在,我仍收到以下错误test1.sh:第1行:在查找匹配的““”test1.sh时出现意外的EOF。第3行:语法错误:意外的文件结尾。@Paulpro你救了我一天。伙计