2017-03-27 3 views
0

私はforループで問題があります。あなたのためにそれを簡単に説明します。ファイルの作成中にエラーが発生するループ

$ for i in `cat serverss`;do ssh -q $i sudo echo "a b c" > /tcb/files/auth/x/xyz;done 
ksh: /tcb/files/auth/x/xyz: cannot create 

ファイルを作成または変更しようとすると、上記のエラーが発生します。 serverssはサーバのリストを持つファイルです。私たちはそれらのシステム上でrootにsudoを持っています。

問題は、私がecho "a b c" > /tcb/files/auth/x/xyzを実行して、完全に動作する個々のサーバーに問題がある場合です。上記のエラーを投げる私のforループの問題は何ですか?

+0

'for'ループ自体はまったく問題ありません。それはsshの引数がどのように与えられるかという問題です。 'ssh -q $ i sudo echo" a bc ">/tcb/files/auth/x/xyz'と' for'ループの中に全く同じ問題があります。 –

+0

もう1つのことは 'sudo echo'は役に立たないということです。シェルは'/tcb/files/auth/x/'をオープンしている特権ではなく' echo'の特権をエスカレートします(stdoutに書いているだけです) xyz'。 –

答えて

0

は、2つの問題がここにあります

  • あなたがしていますリモートシステムではなく、/tcb/files/auth/x/xyzをローカルに開きます。
  • sudo echo foo > barは、barの開設に役立つ特別な特典を提供していません。それはsomethingを実行outputsomething > outputが開くので

この後者です。したがって、sudoは、/tcb/files/auth/x/xyzが開かれても開始されていません。

代わりに、考慮してください。

ssh -q "$i" 'echo "a b c" | sudo tee /tcb/files/auth/x/xyz >/dev/null' 

をリダイレクトがリモートシェルによって実行されるようにsshに渡された文字列の中にあるため、最初の問題が解決されます。 (sshに別々の引数を渡した場合は、それらを空白と組み合わせてそのような文字列を作成するだけで、文字列を自分で作成して制御するほうがよい)。

第二の問題は、tee後はsudoによってエスカレートその特権を持っていた、teeで開かれる/tcb/files/auth/x/xyzを強制することによって解決されます。

+0

チャールズさん、ありがとうございました。実際に私は、ssh -q abc "sed -e 's/\:u_pwd。*/\:u_pwd \ = np \:\\/p'/tcb/files/auth/aのようなsedの代わりにteeを使用しようとしました。あなたはsed -iオプションがKSHで動作しないことに気付いているので、私のファイルを空にします。ファイルのコピーを作成します。sedを実行してください。/ dev/tcb/files/auth/a/abcde>それをsed -eの/ \:u_pwd。*/\:u_pwd \ = np \:\\/p '/tcb/files/auth/a/abcde.tmp>/tcb/files/auth/a/abcdeです。私のポイントは、あなたの代わりにteeを使用するように提案されたエコーのためです。 – salman

+0

実際にはksh-vs-bashではありません。 'sed -i'が動作するかどうかは' sed'のバージョンに依存します。つまり、すでに入力と出力に異なるファイル名を使用しているので、そうする必要があります。 'sed'コマンドが意図したとおりに動作することを確認することをお勧めします。 'ssh -q abc" sed -e 's/\:u_pwd。*/\:u_pwd \ = np \:\\/p' /tcb/files/auth/a/abcde.tmp "'本当に出力がありますか?あなたは意図している?そうでなければ、私は 'set -x'を' ssh -q abc 'set -x; sed -e' s/\:u_pwd。*/\:u_pwd \ = np \:\\/p '/tcb/files/auth/a/abcde.tmp "' ' - デバッグします。 –

+0

はい私のsed作品私は多くのサーバーでテストしました。/s:/ \:u_pwd。*/\:u_pwd \ = NP \:\\/p '/tcb/files/auth/a/abcde.tmp>/tcb/files/auth/a/abcde。要点は、上記のsedコマンドは個々のサーバで適切に実行されますが、サーバのリストのforループに追加されると失敗します。次のエラーが発生します(ksh:/ tcb/files/auth/a/abcde:作成できません)。私はコマンドの二重引用符も持っていましたが運はありませんでした。今のところ私はあなたの提案されたteeコマンドを使用してエコーでファイルを作成することができますが、私はforループ内のファイルを変更することについてはわかりません。ありがとうございます – salman

0

あなたのコマンドは壊れています。リモートでsudo echo "a b c"を実行し、存在しないローカルファイル/tcb/files/auth/x/xyzに標準出力をリダイレクトしようとします。

次の例のように、何とかそれを囲む必要があります。

$ for i in `cat serverss`;do ssh -q $i "sudo echo 'a b c' > /tcb/files/auth/x/xyz";done 

それとも@CharlesDuffyとしては、おそらくprefferう:

$ while read -r line; do ssh -q $line "sudo echo 'a b c' > /tcb/files/auth/x/xyz";done < serverss 
+0

これは[DontReadLinesWithFor](http://mywiki.wooledge.org/DontReadLinesWithFor)に違反しますが、元のものもそうです。 –

+0

いいえ、それは私が好むだろう*ではありません。オペレーティングシステムやシェルに意味を持つ変数の場合、all-caps変数名は[POSIX conventionによって予約されています](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html)です。(普通のシェル変数を設定すると、名前のついた環境変数は上書きされます) –

+0

私は 'cat serverss'で私が言ったように二重引用符を入れようとしました; ssh -q $ i" sudo echo 'abc'>/tcb/files/auth/x/xyz ";完了です。しかし、まだ運がありません。同じエラー – salman

関連する問題