开发者

Bash programming with filesystem functions

I have been busy this week trying to wrap my head around a little Bash program to migrate a CMS from one server to another. The reasopn for this is because I have more tha 40 of these to do, and need to get it done in a timely manner, thus the Bash idea.

Needless to say, I have run into a couple of problems so far, but one of them has halted my development completetly, directory checking.

No I have tried a couple of methods and none of them seem to work really. The catch is that I have to check the folder on a remote server via ssh. Here my example:

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
开发者_JAVA技巧

I get the Error: [: : integer expression expected

Does the [ or test not resturn a 0 which is numerical. ?


Passing strings as arguments to a remote host is not trivial; you need to use arrays. A test example:

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

So your case should be:

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

This is a rare case where using unquoted variable expansion is perfectly fine.


change the shebang to #!/bin/bash -x and look at the output...

  1. you are storing a string in variable SSHRoot using single quotes, meaning that no variables will be expanded, i.e. a $ is still a $. Use double quotes instead, i.e. "

  2. to store the output from a command in bash, use

    var=$(cmd)

  3. the exist status of a command is stored in the variable $?. Do a check on that after the ssh-command

  4. you are never executing the ssh-command in your code

Great link here for bash-programming


Try the following:

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

The variables weren't being replaced in your SSHRoot variable as it's in single quotes. Also, you weren't passing an executable command, so that's why I use bash -c above. It will run the bash commands inside the quoted string.

$? stores the exit value of the last command, in this case the SSHRoot one.


#!/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

So I have incorporated all of the suggestions so far and have one last problem, the FRoot is not getting populated by the complete array values. Other than that I think it now has the subjective approach as suggested @john-keyes, the proper expansion @frederik and the crazy space escapes @l0b0

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜