他のシェルを介してすべてのコマンドライン引数をどのように実行できますか?

他のシェルを介してすべてのコマンドライン引数をどのように実行できますか?

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 "$*"

望むより:

これにより、コマンドラインにすべてのシェル構文を含めることができます。

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"

関連情報