Aynı argümanı kullanarak birden fazla komutu nasıl yürütebilirim?


16

Ben Ubuntu terminalinde zincir eylemleri yapmak mümkün olup olmadığını merak ediyorum:

action 1 on objectA . then action 2 on objectA 

Artık objectA adını tekrarlamak zorunda kalmadan.

Misal:

touch file.js && openEditor "$1" 

ya da böyle bir şey.


Bunu yapmanın birçok yolu var, ancak ihtiyaçlarınıza bağlı. ObjectA nedir? bir dosya ? Hangi eylemlerden bahsediyoruz?
Sergiy Kolodyazhnyy

teşekkürler, genellikle etkili bir dosya, aynı zamanda bir klasör olabilir
HoCo_

3
Burada, &"dokunma" komutunu arka plana gönderir. "Eğer dokunma başarılı olursa editörü aç" &&
glenn jackman

Bu gönderiyi neden çarpıyorsun? Zaten çok sayıda cevabın var ve hatta bir tane bile kabul ettin.
muru

Yanıtlar:


27

Bash History Expansion ile geçerli komut satırının n'inci kelimesine !#:nörn.

$ 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

Hangi bash sürümünü kullandığınızı sorabilir miyim?
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy buGNU bash, version 4.3.48(1)-release
steeldriver

5
bir dizi kelime de belirleyebilirsiniz :touch foo bar && ls -l !#:1-2
glenn jackman

1
@HoCo_ !karakter , etkileşimli bir kabukta olduğunuzda bir geçmiş genişleme ifadesi sunar - yazarken anında komut satırı manipülasyonu içindir ve etkileşimli olmayan komut dosyalarında devre dışı bırakılır
steeldriver

1
@HoCo_ bir senaryoda, argümanın vaktinden önce ne olduğunu bilmelisiniz - bu yüzden örneğin sadece yapabilirsinizarg1=file.js; touch "$arg1" && openEditor "$arg1"
steeldriver

12

Yaygın bir kullanım durumu için kullanışlı bir kısayol vardır. Örneğinizde şunları yapıyorsunuz:

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

İkinci komutta, püf noktası openEditor(arkasından boşluk bırakarak) ve ardından Alt+ yazmaktır .. Bu , son komutun son argümanını ekler , yani . (Herhangi bir nedenden dolayı çalışmazsa da çalışmalıdır.)file.jsAltEsc

Çoğu zaman "nesne" aslında önceki komutun son argümanı olduğundan, bu sık sık kullanılabilir. Hatırlaması kolaydır ve sezgisel olarak kullanılan kabuk kısayolları kümenize hızla entegre olur.

Bununla yapabileceğiniz bir sürü şey var, olasılıklar hakkında derinlemesine bir makale: /programming/4009412/how-to-use-arguments-from-previous-command .

Bonus olarak, bu sadece bash'da değil, komut satırı girişini işlemek için libreadline kullanan tüm programlarda çalışır.


2
Bir ile bu birleştirebilirsiniz haneli argümanı İkinci argüman ulaşmaya, örneğin Altbasın 2.(veya Esc, 2, Esc, .), son argüman basın ikincisini almak için Alt+ -, tip 2ve basın Alt+ .(veya Esc, -2, Esc, .).
tatlı

@dessert Eğer koşarsam argümanlardan birden fazlasını isterim? Ben koşmak echo 1 2 3 4o zaman istiyorum 2ve bir 3sonraki komut için
wjandrea

@dessert Kendim buldum! Aralarında boşluk gibi başka bir şey yazmanız yeterlidir. Bunları birleştirmek için en kolay yol bir boşluk ve sonra geri girmek.
wjandrea

1
@wjandrea tutun Altve tip 2.basın ara çubuğu, tutun Altve tip 3.- Bir dizi isterseniz, kullanım geçmişi genişleme: !!:2-3.
tatlı

9

Varsayılan etkileşimli kabuk bashve komut dosyası kabuğu dashgittikçe, son komutun son argümanını$_ geri çağırmak için kullanabilirsiniz .

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

csh ve tcsh, özellikle komutun son sözcüğü, kullanabileceğiniz !$ve bağımsız değişkenler için geçmiş referanslarına sahiptir !:<index>:

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

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

Genel olarak, objectAbir değişkene ne varsa atamak ve onu birden fazla komut, döngü, vb. Kullanmak daha iyidir . Alternatif olarak, bir işlev bir seçim olabilir:

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

1
Komutu tarihe kaydetmeden önce genişlediğinden $_biraz daha farklı olduğunu belirtmek isterim !#:n. Hala ile komutu gösterecek tarihinin geri gidiş Yani $_süre !#:ngerçek değerle değiştirilmesi olurdu. Her ikisinin de artıları ve eksileri var.
Dan

3
Ayrıca, her zamanki gibi, $_alıntılanmalıdır, aksi takdirde her şey gibi bölünür ve toplanır. (Sadece burada görmüyoruz çünkü echoargümanlarını tek bir boşlukla birleştiriyor.) Ama örneğin touch "hello there"; ls -l $_ işe yaramayacak.
ilkkachu

1
@ Sanırım en büyük profesyonel $_taşınabilir olması. Sonuçta !#:n, bash'a özgüdür.
Sergiy Kolodyazhnyy

3

Steeldriver'ın cevabında verilen tarih yaklaşımına karşı öneriyorum . Bu her zaman kırılgan olan küresel devlete dayanır.

Daha iyi, uygun bir değişken kullanarak gerekli tüm komutlar üzerinde döngü oluşturmaktır:

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

Genel olarak bir sorun olan şey, Bash'in bir arıza olduğunda iptal olmamasıdır, yani aslında touch foo.txt; gedit foo.txtzincirleme yerine davranır &&. Dolayısıyla, güvenli olmak için şunları ekleyebilirsiniz break:

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

1

Bir astarı pişirirken, bazen tekrarladığım şeyi komutta birden çok kez kullandığım bir kabuk değişkenine atarım. Yukarı ok, kontrol + a, kontrol + sağ ok ile farklı bir argüman kullanmak için hatırlayabilir ve düzenleyebilirim t=.

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

Bunun, bir uzantıya veya adda bir varyasyona yapışmayı kolaylaştırdığını unutmayın.

Ayrıca ;, var=value cmdsadece bu komut için bir ortam değişkeni olarak ayarlar ve kabuk bağlamı etkilemez , çünkü bir değişken atama sonra gerekir unutmayın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.