foo (){
sudo -- sh -c "cd /home/rob; echo \"$@\""
}
.bashrc
sudoを特定のディレクトリに変更し、Pythonコマンドを実行するbash関数を作成しようとしています。デモ目的のため、上記の例ではエコに変更しました。
echoコマンドにすべての引数を渡すと述べましたが、次の$@
いずれかが機能します。
$ foo 1
1
$ foo 1 2
2": -c: line 0: unexpected EOF while looking for matching `"'
2": -c: line 1: syntax error: unexpected end of file
何を提供しますか?この関数に複数のパラメータを渡すにはどうすればよいですか?
答え1
set -v
関数に追加すると、何が起こるかを確認できます。
$ f (){ set -v; sudo -- sh -c "cd /tmp; echo \"$@\""; }
$ f 1 2
+ sudo -- sh -c 'cd /tmp; echo "1' '2"'
何が問題なの?使用すると、一重引用符$@
で要約された2つの文字列が生成されます。この分割を望まない場合に使用できます。 Bashのマニュアルページのセクションを参照してください。cd /tmp; echo "1
2"
$*
特殊パラメータ:
@...二重引用符内で拡張が発生すると、各引数は別々の単語に展開されます。 ... If ... 単語内で、最初の引数の拡張は元の単語の先頭に関連付けられ、最後の引数の拡張は元の単語の最後の部分に関連付けられます。
したがって、あなたの場合、単一の文字列(または単語)「xxx$ @ yyy」は2つの文字列「xxx1」と「2yyy」に拡張されます。set -- 1 2 3
setを使用してこれをテストし、単語数$@
をprintf ">%s<" "$@"
確認できます"$@"
(printfは各引数の形式を繰り返すので)。
$ set -- 1 2 3
$ printf ">%s< " "x$@y"
>x1< >2< >3y<
$ printf ">%s< " "x$*y"
>x1 2 3y<
sh -c command
核に引数を渡すには、単一のコマンドの後に引数として配置します。ただし、これはすべてのシェルで機能しない可能性があります。
f (){ set -v; sudo -- sh -c 'cd /tmp; echo "$@"' sh "$@"; }
f 1 2
+ sudo -- sh -c 'cd /tmp; echo "$@"' sh 1 2
追加のsh
パラメーターは、最初のパラメーターがシェル内のプロセス名として使用されるためです。