変数からLinuxプログラムにオプションを渡す

変数からLinuxプログラムにオプションを渡す

必須コード:

echo "$var" | sort -t/ -k 1,1n -k2,2n -k3,3n  

ケースシナリオ:条件に従って動的に生成され、変数に格納されているarrをソートするオプション。どのように渡すことができますか?

option='-k 1,1n -k2,2n'
echo "$var" | sort -t/ "$option"

または

echo "$var" | sort -t/ "$(eval echo "$option")

しかし、何も動作しません。迷子になった文字エラーが発生します。

sort: stray character in field spec: invalid field specification ‘ 1,1n -k 2,2n -k 3,3n’

答え1

以下は、あなたの質問とコマンドラインパラメータを実際に使用する前に変数に保存したい他の状況に具体的に適用される一般的な答えです。

コードの問題は、"$option"コマンドラインでコードを使用するときにsort次のようなことです。一つ議論。この場合は、単に引用符を削除し、シェルに文字列を$optionスペース、タブ、および改行に分割するようにしてから、sort結果リストの一致を呼び出す前に、これらの結果単語に対してファイル名を渡すことでこの問題を解決できます。これはあなたの状況に適していますが、問題を解決するためのあまりエレガントな方法です。

$optionファイル名はグローブパターンを含まず、スペースから文字列を正しく分割することに依存しているため、あまりエレガントです。

より一般的な解決策を得るには、オプションとオプションの引数を配列に入れる必要があります。これにより、必要な各引数を参照できます。次のコードは、配列をサポートするシェル(たとえば)を使用していると仮定していますbash

options=( -k 1,1n -k 2,2n -k 3,3n )

sort -t '/' "${options[@]}" <<<"$var"

引用符拡張を使用すると、${options[@]}配列の各要素がoptions単一のフィールドに展開されます。つまり、optionsコマンドラインですべての要素が個別に引数として引用されているように、シェルは配列を拡張しますsort

配列のないシェルでは、代わりに位置引数リストを使用してください。

set -- -k 1,1n -k 2,2n -k 3,3n

printf '%s\n' "$var" | sort -t '/' "$@"

切り捨てられた最初のコードと同様に、引用は、$@位置引数リストのすべての要素が完全に拡張されることを保証するために不可欠です。ここでも、シェルはフィールドの"$@"リストに展開され、これらのフィールドをユーティリティの引数として提供しますsort

とにかくecho出力に値を使用することは避けたいと思います。これは、シェルの構成と変数の内容に基づいてデータを変更する$varためです。echo

また見なさい:

答え2

コマンドはsort別の引数文字列(たとえば)でオプションを受け取る必要がありますsort -t/ -k 1,1n -k2,2n -k3,3n

たとえば、二重引用符拡張を使用すると、"$option"すべてのオプションが単一の文字列として渡されますsort -t/ -k 1,1n -k2,2n -k3,3n

これを防ぐためにただ引用符を使用しないでくださいについて$option

option='-k 1,1n -k2,2n'
echo "$var" | sort -t/ $option

ソートに使用されるオプションは、-k同じパラメーター文字列()の一部として、またはオプション-k2,2n()の後の次のパラメーター文字列でフィールドを指定できます。フィールド指定がオプション指定子と同じパラメーター文字列の一部である場合は、スペースも許可できます。-k-k 1,1n

echo works | sort -t/ "-k 1,1n" -k2,2n -k3,3n
works

ただし、フィールドの指定後に同じパラメータ文字列に単一の空白文字があっても許可されません。

echo fails | sort -t/ "-k 1,1n " -k2,2n -k3,3n
sort: stray character in field spec: invalid field specification ‘ 1,1n ’

関連情報