簡體   English   中英

使用文件系統功能進行Bash編程

[英]Bash programming with filesystem functions

本周我一直在忙於嘗試將一個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

我收到錯誤消息: [::預期為整數表達式

[或測試不返回數字0。

將shebang更改為#!/bin/bash -x並查看輸出...

  1. 您使用單引號將字符串存儲在變量SSHRoot ,這意味着不會擴展任何變量,即$仍然是$ 請使用雙引號代替,即"

  2. 將命令的輸出存儲在bash中,請使用

    VAR = $(CMD)

  3. 命令的存在狀態存儲在變量$? 在ssh-command之后進行檢查

  4. 您永遠不會在代碼中執行ssh命令

偉大的鏈接這里對於bash編程

請嘗試以下方法:

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

將字符串作為參數傳遞給遠程主機並非易事; 您需要使用數組 一個測試例子:

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

在極少數情況下,使用無引號的變量擴展非常好。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM