関数内でsudoに複数の引数を渡す

関数内でsudoに複数の引数を渡す
foo (){
            sudo -- sh -c "cd /home/rob; echo \"$@\""
}

.bashrcsudoを特定のディレクトリに変更し、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 "12"$*特殊パラメータ:

@...二重引用符内で拡張が発生すると、各引数は別々の単語に展開されます。 ... If ... 単語内で、最初の引数の拡張は元の単語の先頭に関連付けられ、最後の引数の拡張は元の単語の最後の部分に関連付けられます。

したがって、あなたの場合、単一の文字列(または単語)「xxx$ @ yyy」は2つの文字列「xxx1」と「2yyy」に拡張されます。set -- 1 2 3setを使用してこれをテストし、単語数$@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パラメーターは、最初のパラメーターがシェル内のプロセス名として使用されるためです。

おすすめ記事