いくつかの行を印刷する関数がありますが、それを別の関数の引数として使用したいと思います。
lsx() {
echo 1 is one
echo 2 are two
}
somefun() {
for arg in "$@"; do
echo "arg='$arg'"
done
}
somefun()
fromラインをlsx()
パラメータとして使用して、「エレガントに」電話をかける方法は?
私が今やっていることは、ループを使って行を繰り返し、(編集:while + subshellのため動作しません)。私は簡単な(または植え込み可能な)方法があるべきだと思いますが、それを理解することはできません。while
行を配列に格納することです。しかし、これは見た目には良くなく、あまりにも効率的です。
(somefun
外部コマンドの場合は、次を使用します。パラメータしかしそれは真実ではない。 )
答え1
xargsなし
$ ( IFS=$'\n'; somefun $(lsx) )
arg='1 is one'
arg='2 are two'
IFS
グローバル以外のローカル変更が行われるようにサブシェルが使用されます。
限定:これは出力がパス名拡張の影響を受け、lsx
これが問題になる可能性があります。
xargsによる
xargsを使用してシェル機能にアクセスするには、シェルを実行する必要があります。サブシェルにアクセスするには、somefun
まずそれをエクスポートする必要があります。したがって:
$ export -f somefun
$ lsx | xargs -d'\n' bash -c 'somefun "$@"' SomeFun
arg='1 is one'
arg='2 are two'
最初の引数は、エラーメッセージのプログラム名bash
に割り当てられて使用されます。$0
どんな言葉でも可能です。ここではSomeFun
。
パス名拡張の問題の例
$ lsx() { echo '1 is one*'; echo '2 are two*'; }
$ touch '1 is one'{1..3} two{a..c}
$ ( IFS=$'\n'; somefun $(lsx) )
arg='1 is one1'
arg='1 is one2'
arg='1 is one3'
arg='2 are two*'
ご覧のとおり、出力の最初の行は3行に拡張されています。
シェルが最初に実行されました噴射出力に$(lsx)
。 IFS が改行に設定されているため、出力は複数行に分割されます。その後、シェルが実行されます。パス名拡張。 globと一致するファイルがあるため、1 is one*
globはこれらの名前のリストに展開されます。この例では、globと一致するファイルがないため、2 is two*
globは拡張されません。 (デフォルトIFSでは2 is two*
3つの単語に分割され、3番目の単語はfileとに一致しtwoa
ますtwob
。twoc
)
このxargs
方法はパス名の拡張を防ぎます。
$ export -f somefun
$ lsx | xargs -d'\n' bash -c 'somefun "$@"' SomeFun
arg='1 is one*'
arg='2 are two*'
答え2
簡単な解決策:
IFS="
"
somefun $(lsx)