【问题标题】:Bash programming with filesystem functions使用文件系统函数进行 Bash 编程
【发布时间】:2011-09-30 09:59:01
【问题描述】:

这周我一直很忙,试图围绕一个小 Bash 程序将 CMS 从一台服务器迁移到另一台服务器。这样做的原因是因为我有超过 40 件事情要做,并且需要及时完成,这就是 Bash 的想法。

不用说,到目前为止,我遇到了几个问题,但其中一个完全停止了我的开发,即目录检查。

不,我尝试了几种方法,但似乎都没有真正奏效。问题是我必须通过 ssh 检查远程服务器上的文件夹。这是我的例子:

ExSshRsa=~/.ssh/id_rsa
ExSshPort=22
ExSshHost=localhost
ExRoot=/var/www/
echo -n "Verifying Root access $ExRoot..."
SSHRoot='ssh -i $ExSshRsa -p $ExSshPort $ExSshHost [ -d $ExRoot ] || exit 1 '
echo $SSHRoot 
if [ "$SSHRoot" -eq 0 ]
    then
        echo "OK"
    else
        echo "FAIL"
fi

我得到错误:[: : integer expression expected

[ 或测试是否不会返回数字 0。 ?

【问题讨论】:

  • 你意识到你没有运行那个 ssh 调用,只是显示它,对吧?
  • 我将行改为 SSHRoot=$( ssh -i $ExSshRsa -p $ExSshPort $ExSshHost [ -d $ExRoot ] && echo "0" && exit 0 || echo "1" && exit 1 ) 它似乎工作...?!?
  • 我多么想更改标题中的错字...
  • 哦,没发现 :-) 您应该可以在您的问题下方使用 edit 链接。它是否阻止您进行该编辑? (如果是,错误是什么?)

标签: bash ssh directory


【解决方案1】:

将字符串作为参数传递给远程主机并非易事;你需要use arrays。一个测试例子:

declare -a cmd=(touch "file name with spaces")
printf -v escaped_cmd_str '%q ' "${cmd[@]}"
ssh localhost $escaped_cmd
ssh localhost ls # Should return "file name with spaces" on a separate line

所以你的情况应该是:

ExSshRsa=~/.ssh/id_rsa
ExSshPort=22
ExSshHost=localhost
ExRoot=/var/www/
echo -n "Verifying Root access $ExRoot..."

declare -a cmd=( '[' -d "$ExRoot" ']' ) # Need to quote "[" since it's a Bash-specific symbol
printf -v escaped_cmd_str '%q ' "${cmd[@]}"

if ssh -i "$ExSshRsa" -p "$ExSshPort" "$ExSshHost" $escaped_cmd
then
    echo "OK"
else
    echo "FAIL"
fi

这是一种罕见的情况,使用 unquoted variable expansion 完全没问题。

【讨论】:

  • 感谢您的提示,因为这将是我将遇到的下一个问题,但首先我试图让主观编程工作......
  • escaped_cmd 存储为数组并不会在printf -v escaped_cmd_str '%q ' "${cmd[@]}" 上为您买任何东西,并通过ssh "$escaped_cmd_str"。请记住,ssh 将它作为参数传递的所有字符串连接在一起——所以你正在生成一个转义字符串,将它分成几部分,然后让 ssh 重新组合它......到什么目的?
  • @CharlesDuffy 不错的捷径!
【解决方案2】:

将shebang更改为#!/bin/bash -x并查看输出...

  1. 您使用单引号将字符串存储在变量SSHRoot 中,这意味着不会扩展任何变量,即$ 仍然是$。改用双引号,即"

  2. 要将命令的输出存储在 bash 中,请使用

    var=$(cmd)

  3. 命令的存在状态存储在变量$?中。在 ssh-command 之后检查一下

  4. 您永远不会在代码中执行 ssh 命令

用于 bash 编程的链接 here

【讨论】:

    【解决方案3】:

    尝试以下方法:

    ExSshRsa=~/.ssh/id_rsa
    ExSshPort=22
    ExSshHost=localhost
    ExRoot=/var/www/
    echo -n "Verifying Root access $ExRoot..."
    cmd="bash -c \"[ -d $ExRoot ] || exit 1\""
    SSHRoot="ssh -i $ExSshRsa -p $ExSshPort $ExSshHost ${cmd}"
    $SSHRoot 
    if [ $? -eq 0 ]
        then
            echo "OK"
        else
            echo "FAIL"
    fi
    

    SSHRoot 变量中的变量没有被替换,因为它位于单引号中。此外,您没有传递可执行命令,这就是我在上面使用bash -c 的原因。它将在带引号的字符串中运行 bash 命令。

    $? 存储最后一条命令的退出值,在本例中为 SSHRoot

    【讨论】:

    • 你的方法更好吗?我的方法似乎行得通,但我更愿意以正确的方式去做...SSHRoot=$( ssh -i $ExSshRsa -p $ExSshPort $ExSshHost [ -d $ExRoot ] && echo "0" && exit 0 || echo "1" && exit 1 )
    • @WillemP.Botha 在很多情况下更好是主观的。如果你对你所拥有的感到满意,那就开火吧。我认为我的解决方案更容易阅读。
    • 我喜欢主观的方法,并且正在尝试像这样重写它,这样可以更好地阅读
    • if 之前没有 $SSHRoot 脚本不起作用,这真的没有意义了......也许我可以主观地使用变量扩展......
    • 抱歉,Willem,你是说你的版本还是我的版本不行?我今天早上测试了我的,它有效。
    【解决方案4】:
    #!/bin/bash
    ExSshRsa=~/.ssh/id_rsa
    ExSshPort=22
    ExSshHost=localhost
    ExBase='/tmp/'
    ExRoot='one space/'
    declare -a AExRoot
    for argR in "${ExRoot[@]}"
        do
            ExRoot+=($(printf %q "$argR"))
        done
    clear
    FRoot=( $ExBase${ExRoot[@]} )
    echo -n "Verifying Root access $FRoot..."
    SSHRootTest="bash -c \"[ -d $FRoot ] && echo 0 && exit 0 || echo 1 && exit 1\""
    SSHRoot=$( ssh -i $ExSshRsa -p $ExSshPort $ExSshHost ${SSHRootTest})
    if [ $? -eq 0 ]
        then
            echo -en "\e[1;32mOK\e[0;37;m..."
        else
            echo -en "\e[1;31mFAIL\e[0;37;m..."
    fi
    sleep 1
    if [ -w $FRoot ]
        then 
            echo -e "\e[1;32mwritable\e[0;37;m"
        else 
            echo -e "\e[1;31mNOT writeable\e[0;37;m"
    fi
    echo -e "\e[0;m"
    exit 0
    

    所以到目前为止,我已经整合了所有建议,并且还有最后一个问题,FRoot 没有被完整的数组值填充。除此之外,我认为它现在具有@john-keyes 建议的主观方法,@frederik 的适当扩展和疯狂的空间逃脱@l0b0

    【讨论】:

    • 实际上,现在阅读它,写入测试无法正常工作,因为它正在测试本地文件系统,但除此之外,我可以像之前的测试一样修复它,重要的部分是尝试让数组将所有值连接回 FRoot 变量与带引号的空格值....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    相关资源
    最近更新 更多