
リモートサーバーから複数のファイルを削除したいです。すべてのファイルを1つのスクリプト配列に配置し、別のスクリプトを呼び出してファイルを削除します。
「${b[@]}」の出力は次のとおりです。
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-00-01.tar.gz
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-30-01.tar.gz
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_05-00-02.tar.gz
ファイルを削除するスクリプトは次のとおりです。
#!/bin/bash
file="$1"
sshpass -p 'password' ssh [email protected] "echo "$file""
通話中にbash /tmp/1.sh "'${b[@]}'"
エラーが発生しました。
bash: -c: line 0: unexpected EOF while looking for matching `''
bash: -c: line 1: syntax error: unexpected end of file
そして呼び出されると、bash /tmp/1.sh "${b[@]}"
ファイル変数にのみファイルを割り当てます。
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-00-01.tar.gz
上記のスクリプトで、空白を含む配列の値をファイル変数に割り当てる方法を教えてください。
更新::declare -a file=("$@")
他のスクリプトで設定して動作しました。しかし、単に配列ではなく、より多くのパラメータを送信するにはどうすればよいですか?
答え1
sshpass -p 'password' ssh [email protected] "some_cmd $(printf '%q ' "$@")"
sshpass -p 'password' ssh [email protected] "f() { for i; do some_cmd "$i"; done; }; f $(printf '%q ' some_cmd "$@")"
sshpassのマニュアルページによると、
sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
"$@"
したがって、次のようにsshコマンドにすべてを渡すことができるはずです。
sshpass -p 'password' ssh [email protected] printf '%q\n' "$@"
ターゲットコマンドはこの種類のパラメータ処理を処理できない可能性があるため、この問題を解決できます。
sshpass -p 'password' 'k(){ for i; do echo $i; done; }; k' "$@"
スペースを使ってテストしましょう。
set -- 'foo bar' $'lorem\nipsum\td'
# paste that two lines.. Since I don't have sshpass installed, just using ssh.
ssh
明らかに台無しにされた。偽の殻をつなぎ、何が起こるのか見てみましょう。
#!/bin/bash
# /bin/mysh
# someone:x:1000:1000:FOo,,Bar,:/home/foo:/bin/mysh
printf '%q ' bash "$@"; echo;
exec bash -xv --norc "$@";
よく。やってみよう
bash -c $'printf %q\\n foo bar lorem\nipsum\td'
printf %q\n foo bar lorem
+ printf %qn foo bar lorem
ipsum d
+ ipsum d
bash: line 1: ipsum: command not found
明らかに、sshはこれらのものをスペースで連結します。クールではありません。
事前にエスケープ処理するとprintf '%q '
取得できます。TL;DR答え。 EOFと失敗も理解できます-c
。
注:sshがバージョンによって-cを異なる方法で実行しているかどうかはわかりません。自分で試してみることもできます。少なくともOpenSSH 7.1(ssh.c:955-969)。
答え2
質問のタイトルに答えるには:
[script]を使用して、スペースを含む複数のパラメータをsshに渡します。
次の引用符は使用しないことをお勧めします。
ssh [email protected] echo "\"arg 1\" \"arg 2\""
"arg 1"
...最初と2番目の引数として送信されます"arg 2"
(この場合、リモートシステムのechoコマンドの出力結果)。
arg 1 arg 2
注:echoコマンドは各パラメーターを出力し、パラメーター間にスペースがあります。ただし、単一の引数に含まれるスペースは保持されます。空白が実際に議論の一部であるという証拠として、これを質問のタイトルで要求することです。
答え3
最初のスクリプトは次のようになります。
#!/bin/bash
password="mypassword"
filelist=("$@")
for file in "${filelist[@]}";
do
sshpass -p '$password' ssh [email protected] "echo \"$file\""
done
forループは各ファイルをコマンドに提供します。
エラーは次のとおりです。
bash: -c: line 0: unexpected EOF while looking for matching `''
スクリプトを呼び出す方法と関係があるとします。次のように呼び出す必要があります(1行)。
$ ./1.sh "${b[@]}"