私はこのようなbashスクリプトを持っています
export pipedargument="| sort -n"
ls $pipedargument
しかし、エラーが発生します。
ls: |: No such file or directory
ls: sort: No such file or directory
"| sort -n"
内容を に渡されたパラメータとして扱うようですls
。
通常のパイプコマンドのように処理されるようにどのようにエスケープしますか?
これを条件付きに設定しようとしています$pipedargument
。条件付きで別のバージョンのコマンドを実行できるようですが、上記のように動作させる方法があるかどうか疑問に思います。
答え1
|
あなたは正しいです、そうしないでください。その理由は、シェルが変数置換を実行する前に、すでにパイプを見つけてコマンドに分割するためです。したがって、|
それは別のキャラクターと見なされます。
考えられる解決策の1つは、パイプ文字を文字通り配置することです。
$ cmd="sort -n"
$ ls | $cmd
cat
パイプが必要ない場合は、「nop」またはプレースホルダとして使用できます。
$ cmd=cat
$ ls | $cmd
より良いアプローチ:配列
より洗練されたアプローチは、bash
通常の文字列の代わりに配列を使用することです。
$ cmd=(sort -n)
$ ls | "${cmd[@]}"
cmd
引用符付き引数を含むコマンドが必要な場合は、配列の利点が重要になります。
答え2
eval
次のコマンドを使用できます。
eval "ls $pipedargument"
または、次のように関数を定義する方が良いでしょう。
sorted() { "$@" | sort -n; }
次に、必須パラメータを使用して呼び出します。
sorted ls /tmp
答え3
私はこれに関数を使用します。それは次のとおりです。
### usage pipedargument cmd args ###
pipedargument()
{
sort -n <<< "$( "$@" )"
}
$ pipedargument /sbin/ifconfig eth0
RX bytes:5904986765 (5.4 GiB) TX bytes:714370767 (681.2 MiB)
RX packets:5981427 errors:0 dropped:0 overruns:0 frame:0
TX packets:4403989 errors:0 dropped:0 overruns:0 carrier:0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
collisions:0 txqueuelen:1000
inet addr:XXX.XXX.X.XX Bcast:XXX.XXX.X.XXX Mask:255.255.255.0
inet6 addr: xx00::0x0x:00xx:xx0:000/00 Scope:Link
eth0 Link encap:Ethernet HWaddr 0x:0x:00:x0:00:00