エイリアスなしで変数にコマンドを割り当てる

エイリアスなしで変数にコマンドを割り当てる

私はbashでalias

g=date
$g
Mon Jun 27 13:00:40 MYT 2016

これはうまくいきます。別の例は次のとおりです。

jj="ping yahoo.com"
$jj
PING yahoo.com (98.138.253.109) 56(84) bytes of data.
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=1 ttl=41 time=347 ms
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=2 ttl=41 time=345 ms
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=3 ttl=41 time=345 ms

このバージョンのbashを使用していますbash --version GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

調べたスタック交換そしてTLDP吸収値しかし、私たちがこれを行うことができることが見つかりませんでした。それでは、これはbashの新機能ですか、それとも見落とされていますか?これが考慮されるか。コマンドの置き換え

答え1

対話型を使用すると、シェルは端末装置から入力行を読み取ります。 1行を入力した後、Fに分割してトークン(単語と演算子).これにより、トークンまたは単語が特定の順序で展開または解析されます。

注:通常、Advanced Bash Scripting Guide、オンラインチュートリアル、書籍、Stack Exchangeなどの補助ソースではなく、プロジェクトドキュメントや業界仕様などの正式な情報ソースを参照する方が良いです。これらの補助ソースは、概念をより簡単な言語で紹介して説明するのに役立ちますが、一般的に公式文書を完成または置き換えるためのものではありません。補助ソースの情報も最新の情報ではない可能性があります。

この場合、簡単なコマンドを解析するためのPOSIX仕様指摘

  1. 変数の割り当てやリダイレクト以外の単語は拡張する必要があります。拡張後に残りのフィールドがある場合、最初のフィールドはコマンド名として扱われ、残りのフィールドはコマンドの引数です。

これ簡単なコマンド拡張の Bash マニュアルセクションも指摘した

  1. 変数の割り当てやリダイレクト以外の単語は拡張されます(シェル拡張を参照)。拡張後に残りの単語がある場合、最初の単語はコマンド名として扱われ、残りの単語は引数として扱われます。

答え2

これはコマンド置換ではありません。変える置換。コマンドを変数に代入するのではなく、文字列を代入します。コマンドは、値が割り当てられたときではなく、変数を使用したときに実行されます。

g=date文字列をdate変数に保存しますg。その後、を実行するとecho "$g"値が印刷されますgdate後に改行文字が表示されます)。なぜなら、値がgコマンドの最初の引数として渡されるからです。echorunの場合、"$g"文字列dateはコマンドの最初の位置に配置されるため、これはコマンド名になります。

その後、$jj2番目の要素が機能します。変数拡張は引用符の外にあるので「分割+グローブ演算子」この値に適用されます。この場合、これは値がスペースjjで区切られた2つの単語に分割されることを意味します。したがって、単語はpingコマンド位置で終わり、単語はyahoo.com最初の引数です。

答え3

これは予想される動作であり、長年にわたって動作してきました。スクリプトからコマンドを書くのに便利です。

たとえば、特定の入力をパイプに送信する前に解凍して出力を圧縮する必要がある場合がありますが、そうでない場合があります。使用bash:

if (( use_compression == 1 )); then
   infilter='gzip -d -c'
   outfilter='gzip -c'
else
   infilter='cat'
   outfilter='cat'
fi

$infilter "$indatafile" | somepipeline | $outfilter >"$outdatafile"

コマンド置換ですか?いいえ。 「コマンド置換」とは、特に$(...)バックティック変形を対応する出力に置き換えることを意味する。

これは反対ですパラメータ拡張、これは単にパラメータをその値に置き換えます。これは、コマンドが実際に実行される前に発生するため、機能することです。

これは、次のタスクをコマンドラインでも実行できることを意味します。

$ decompress='gzip -d -c'
$ ${decompress/g/gun/} filename >unzippedfilename

gunzip代わりに実行されますgzip

編集する:エイリアス情報。

このマニュアルには次のようにbash記載されています。

ほとんどすべての目的で、エイリアスはシェル関数に置き換えられます。

...同意します。

エイリアスは、次のような短いコンテンツに適しています。

alias ls="ls -F"

(これは私のシェルセッションの唯一のエイリアスです。)

コマンドラインで「alias」コマンドでパラメータ拡張を使用したくない場合があります。他の理由がない場合は、入力すると首の痛みが発生する可能性があります。パラメータ拡張は、配管のように少し複雑な作業を許可しません。

適切に複雑な作業を定期的に実行する場合は、代わりにシェル機能を使用してください。

許可された答えを例に挙げてみましょう。U&Lの問題(以下のコメントにリンクを入れました):

alias my_File='ls -f | grep -v /'

このエイリアスは明らかに動作しますが、

my_File='ls -f | grep -v /'

$my_Fileその後、これをコマンドラインでコマンドとして使用しようとするとうまくいきません(このU&Lスレッドで説明されている理由)。

シェル関数を使用すると、引数渡しなどの操作も実行できます。

function my_File {
    ls -l "$@" | fgrep -v '/'
}

$ my_File -iF symlink
84416642 lrwxr-xr-x  1 kk  staff  4 Jun 27 09:03 symlink@ -> file

答え4

これは何十年もの間(文字通り)周りにあり、このように機能した概念であるシェル変数を使用しています。

コマンドラインに変数を配置すると、シェルはそれを置き換えてからコマンドを実行するため、変数が先頭にある場合は明らかにコマンドとして扱われます。

関連情報