同じ引数を使用して複数のコマンドを実行するにはどうすればよいですか?


16

Ubuntuターミナルで次のようなチェーンアクションを実行できるかどうか疑問に思います。

action 1 on objectA . then action 2 on objectA 

もうobjectAの名前を繰り返す必要はありません。

例:

touch file.js && openEditor "$1" 

またはそのようなもの。


それを行う方法はたくさんありますが、ニーズによって異なります。objectAとは?ファイル ?私たちが話しているアクションは何ですか?
セルギーKolodyazhnyy

おかげで、通常は事実上ファイルがフォルダーになることもあります
HoCo_

3
ここで&は、「タッチ」コマンドをバックグラウンドに送信します。「タッチが成功したらエディターを開く」ことを意図している場合は、&&代わりに
グレンジャックマン

なぜこの投稿にぶつかったのですか?あなたはすでにたくさんの答えを得て、それを受け入れさえしました。
ムル

回答:


27

bash History Expansionを使用すると、!#:nたとえば次のコマンドを使用して、現在のコマンドラインのn番目の単語を参照できます。

$ touch foobar && ls -l !#:1
touch foobar && ls -l foobar
-rw-rw---- 1 steeldriver steeldriver 0 Jun 20 14:54 foobar

$ touch foo bar && ls -l !#:2
touch foo bar && ls -l bar
-rw-rw-r-- 1 steeldriver steeldriver 12 Jun 20 14:58 bar

あなたが使用しているbashのバージョンを尋ねてもいいですか?
セルギーKolodyazhnyy

@SergiyKolodyazhnyyこれはGNU bash, version 4.3.48(1)-release
steeldriver

5
あなたも指定することができた単語の範囲をtouch foo bar && ls -l !#:1-2
グレンはジャックマン

1
@HoCo_ !文字は、あなたがしている際に履歴展開式を導入し、インタラクティブシェルで、それはあなたがしているタイピングとしてオンザフライコマンドライン操作のためのものだ、と無効内部非対話型スクリプトです-
steeldriver

1
@HoCo_スクリプトでは、引数が何であるかを事前に知っておく必要があります。たとえば、次のようにできますarg1=file.js; touch "$arg1" && openEditor "$arg1"
-steeldriver

12

一般的なユースケースには便利なショートカットがあります。あなたの例では:

$ touch file.js
$ openEditor <alt>+<.>

2番目のコマンドの秘trickは、openEditor(後にスペースを付けて)書き込み、その後にAlt+を付けること.です。これにより、最後のコマンドの最後の引数が挿入されます。file.jsます。(Alt何らかの理由で動作しない場合はEsc、同様に動作するはずです。)

多くの場合、「オブジェクト」は実際に前のコマンドの最後の引数であるため、頻繁に使用できます。覚えやすく、直観的に使用される一連のシェルショートカットにすばやく統合できます。

これでできることはたくさんあります。可能性についての詳細な記事は次のとおりです。 ます https //stackoverflow.com/questions/4009412/how-to-use-arguments-from-previous-command

ボーナスとして、これはbashだけでなく、コマンドライン入力の処理にlibreadlineを使用するすべてのプログラムで機能します。


2
あなたはでこれを組み合わせることができ桁の引数第二引数のホールドを取得するなど、Alt押しを2.(またはEsc2Esc.最後の引数プレスに2つ目を取得するには、)Alt+ -、タイプ2キーを押しAlt+ .(またはEsc-2Esc.)。
デザート

@dessert複数の引数が必要な場合はどうなりますか?例えば私が実行echo 1 2 3 4し、私がしたい23、次のコマンドのために
wjandrea

@dessert自分で見つけた!間にスペースなどの何かを入力するだけです。それらを連結するには、スペースを入力してからバックスペースを入力するのが最も簡単な方法です。
-wjandrea

1
@wjandrea hold Altand type 2.、スペースバーを押し、ホールドAltして入力3.-範囲が必要な場合は、履歴展開を使用します!!:2-3
デザート

9

デフォルトの対話型シェルbashおよびスクリプトシェルに関する限り、最後のコマンドの最後の引数を呼び出すdashために使用できます。$_

$ echo "Hello World"; echo same "$_"
Hello World
same Hello World

cshとtcshには履歴参照があります。特にコマンドの最後の単語については、を使用でき!$、個々の引数については-を使用できます!:<index>

~% echo foo bar
foo bar
~% echo !$
echo bar
bar

% echo bar baz
bar baz
% echo !:1
echo bar
bar

一般objectAに、変数に何でも割り当てて、複数のコマンド、ループなどで使用することをお勧めします。代わりに、関数を選択することもできます。

$ foo(){ echo "$@"; stat --print="%F\n" "$@";}
$ foo testdir
testdir
directory

1
コマンドを履歴に保存する前に後者が展開される$_場合!#:nとは少し異なる動作をすることを指摘したいと思います。だから、歴史の中で起こって背中はまだでコマンド表示されるでしょう$_しばらくは!#:nその実際の値に置き換えされていたであろう。どちらにも長所と短所があります。
ダン

3
また、いつもの$_ように引用符で囲む必要があります。そうしないと、他のすべてのように分割されてグロブされます。(echo引数を単一のスペースで結合しているため、ここでは表示されません。)しかし、たとえばtouch "hello there"; ls -l $_ 動作しません。
-ilkkachu

1
@Dan最大の長所$_は、ポータブルだということです。結局のところ、!#:nbash固有です。
セルギーKolodyazhnyy

3

steeldriver's answerに記載されている歴史的アプローチに反対することをお勧めします。これは、常に脆弱なグローバル状態に依存しています。

より適切なのは、適切な変数を使用して、必要なすべてのコマンドをループ処理することです。

$ for c in touch gedit; do $c foo.txt; done

一般的に少し問題なのは、障害が発生してもBashが中断しないことです。つまり、これはtouch foo.txt; gedit foo.txtで連鎖する代わりに実際に動作し&&ます。したがって、安全にするために、次を追加できますbreak

$ for c in touch gedit; do $c foo.txt || break; done

1

ワンライナーを作成するとき、コマンドで複数回使用するシェル変数に繰り返しを割り当てます。上矢印、control + a、control + right-arrowの異なる引数を使用して、カーソルをに近づけるように呼び出して編集することができますt=

t=testloop; asm-link -d "$t.asm" && perf stat -r2 ./"$t"

これにより、拡張機能や名前のバリエーションを簡単に追加できることに注意してください。

また;、変数の割り当て後にvar=value cmdコマンドが必要になることに注意してください。これは、それをそのコマンドの環境変数として設定するだけで、シェルコンテキストには影響しないからです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.