tempenv
次のように使用したいスクリプトがあります。
$ tempenv ls -l
tempenv
次のようになります。
#!/bin/bash
setarch ... /bin/bash -c $@
しかし、期待どおりに動作しません。代わりに、最初の引数だけを実行し、他の引数は無視します。tempenv ls -l
のように走っていましたtempenv ls
。
答え1
man bash
:
-c
-cオプションがある場合は、オプションではなく最初の引数command_stringからコマンドを読み取ります。 command_stringの後に引数がある場合、最初の引数は$ 0に割り当てられ、残りの引数は位置引数に割り当てられます。 $ 0の指定は、警告メッセージとエラーメッセージに使用されるシェルの名前を設定します。
tempenv () { bash -c 'set -x; : "$@"' foo "$@"; }
tempenv ls -l 'foo bar'
+ : ls -l 'foo bar'
したがって、これはあなたに役立ちます:
#!/bin/bash
setarch ... /bin/bash -c '"$@"' tempenv-subshell "$@"
答え2
シェルの-c
オプションは、コマンドラインを引数として2つに分割し$@
ますls -l
。 (同じです"$@"
。ただし、引数文字列に空白がそのまま残るので、直接的な助けにはなりません。)
したがって、実際のコマンドラインを渡したい場合は、スクリプトに文字列のみを渡してからを使用して渡すか、必要に応じてスクリプトのすべてのパラメータをsh -c "$1"
文字列に連結してからを使用しますsh -c "$*"
。
#!/bin/bash
setarch ... /bin/bash -c "$*"
望むより:
- (Bash)シェルの特別なパラメータ/変数は何ですか?
- https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html
これにより、コマンドラインにすべてのシェル構文を含めることができます。
tempenv 'ls -l; echo $SOMEVAR'
tempenv '[ some test ] && echo true'
ただし、スペースを含むファイル名など、スペースを含める必要があるパラメーターは2回引用する必要があります。
tempenv 'ls -l "Some Document.txt"'
答え3
tempenv
スクリプトを次のように呼び出すとしますtempenv ls -l
。つまり、コマンド名とそのコマンドの引数という2つの引数を渡すと、実際には好きなように聞こえます。
#!/bin/sh -
exec setarch ... "$@"
つまり、tempenv
さまざまなアーキテクチャで指定されたパラメータを使用して特定のコマンドを実行しようとします。
一部のシェルが他のアーキテクチャで一部のコードを解釈できるようにするには、選択したシェルtempenv 'ls -l'
で解釈されるコードと呼ぶことができます。ls -l
コードは次のとおりです。
#! /bin/sh -
if [ "$#" -ne 1 ]; then
printf >&2 '%s\n' "Usage: $0 <code-in-bash-language>"
exit 1
fi
bash_code=$1
exec setarch ... /bin/bash -c -- "$bash_code"