Pertanyaan Bagaimana saya menjalankan beberapa perintah menggunakan argumen yang sama?


Saya ingin tahu apakah mungkin untuk membuat aksi berantai di terminal Ubuntu seperti:

action 1 on objectA . then action 2 on objectA 

tanpa harus mengulang nama objectA lagi.

Contoh:

touch file.js && openEditor "$1" 

atau semacam itu.


15
2018-06-20 18:44


asal


Ada banyak cara untuk melakukan itu, tetapi tergantung pada kebutuhan Anda. Apa itu objectA? file ? Apa tindakan yang sedang kita bicarakan? - Sergiy Kolodyazhnyy
terima kasih, biasanya file yang efektif, bisa juga berupa folder - HoCo_
Sini, & akan mengirimkan perintah "sentuh" ​​ke latar belakang. Jika Anda bermaksud "buka editor jika sentuhan berhasil", maka Anda mau && sebagai gantinya - glenn jackman
Mengapa Anda menabrak pos ini? Anda sudah mendapat banyak jawaban dan bahkan menerima satu. - muru


Jawaban:


Dengan bash Ekspansi Riwayat, Anda dapat merujuk ke kata n dari baris perintah saat ini menggunakan !#:n misalnya

$ 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

26
2018-06-20 18:59



Bolehkah saya bertanya, versi bash mana yang Anda gunakan? - Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy ini GNU bash, version 4.3.48(1)-release - steeldriver
Anda juga bisa menentukan berbagai kata: touch foo bar && ls -l !#:1-2 - glenn jackman


Ada cara pintas praktis untuk kasus penggunaan umum. Dalam contoh yang Anda lakukan:

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

Di perintah kedua, triknya adalah menulis openEditor (dengan spasi setelahnya) diikuti oleh Alt+.. Ini akan memasukkan terakhir argumen dari terakhir perintah, yang mana file.js. (Jika tidak berhasil Alt untuk beberapa alasan, ESC harus bekerja juga.)

Karena sering kali "objek" adalah argumen terakhir dari perintah sebelumnya, ini dapat sering digunakan. Ini mudah diingat dan akan cepat terintegrasi ke dalam kumpulan pintasan shell yang digunakan secara intuitif.

Ada banyak hal yang dapat Anda lakukan dengan ini, inilah artikel mendalam tentang kemungkinannya: https://stackoverflow.com/questions/4009412/how-to-use-arguments-from-previous-command.

Sebagai bonus ini akan bekerja tidak hanya di bash tetapi di semua program yang menggunakan libreadline untuk memproses input baris perintah.


11
2018-06-21 00:52



Anda dapat menggabungkan ini dengan argumen digit, mis. untuk mendapatkan argumen kedua Alt dan tekan 2. (atau Esc, 2, Esc, .), untuk mendapatkan penekanan argumen kedua hingga terakhir Alt+-, ketik 2 dan tekan Alt+. (atau Esc, -2, Esc, .). - dessert
@dessert Bagaimana jika saya menjalankan ingin lebih dari satu argumen? Misalnya. saya berlari echo 1 2 3 4 maka saya mau 2 dan 3 untuk perintah selanjutnya - wjandrea
@dessert Menemukannya sendiri! Anda hanya perlu mengetikkan sesuatu yang lain di antara mereka, seperti ruang. Untuk menggabungkannya, cara termudah adalah mengetik spasi kemudian mundur. - wjandrea
@wjandrea terus Alt dan ketik 2., tekan bilah spasi, tahan Alt dan ketik 3. - jika Anda menginginkan rentang, gunakan pemekaran sejarah: !!:2-3. - dessert


Sejauh shell interaktif default bash dan scripting shell dash pergi, Anda dapat menggunakan $_ untuk mengingat kembali argumen terakhir dari perintah terakhir.

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

csh dan tcsh memiliki referensi riwayat, khususnya untuk kata terakhir dari perintah, yang dapat Anda gunakan !$, dan untuk argumen individu - !:<index>:

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

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

Secara umum, lebih baik menetapkan apa pun itu objectA ke variabel, dan menggunakannya dalam beberapa perintah, loop, dll. Atau, fungsi bisa menjadi pilihan:

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

9
2018-06-20 18:55



Saya hanya ingin menunjukkan itu $_ bekerja sedikit berbeda dari !#:n sebagai yang terakhir diperluas sebelum menyimpan perintah dalam sejarah. Jadi kembali dalam sejarah masih akan menunjukkan perintah dengan $_ sementara !#:n akan diganti dengan nilai sebenarnya. Keduanya memiliki pro dan kontra. - Dan
Juga, seperti biasa, $_ harus dikutip, karena jika tidak itu akan dibagi dan digulung seperti yang lainnya. (Kami hanya tidak melihatnya di sini sejak echo menggabungkan argumennya dengan satu spasi.) Tapi mis. touch "hello there"; ls -l $_  tidak akan berfungsi. - ilkkachu
@Dan saya pikir pro terbesar untuk $_ apakah itu portabel. Lagipula, !#:n adalah spesifik-bash. - Sergiy Kolodyazhnyy


Saya akan merekomendasikan melawan pendekatan sejarah yang diberikan Jawaban steeldriver. Ini bergantung pada kondisi global, yang selalu rapuh.

Lebih baik adalah loop di depan atas semua perintah yang dibutuhkan, menggunakan variabe yang tepat:

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

Apa sedikit masalah pada umumnya adalah bahwa Bash tidak membatalkan ketika ada kegagalan, yaitu ini benar-benar berperilaku seperti itu touch foo.txt; gedit foo.txt bukannya berantai dengan &&. Jadi, untuk amannya Anda bisa menambahkan break:

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

3
2018-06-21 13:57





Ketika memasak satu baris, saya kadang-kadang menetapkan hal saya diulang ke variabel shell yang saya gunakan beberapa kali dalam perintah. Saya dapat mengingat dan mengeditnya untuk menggunakan argumen berbeda dengan panah atas, kontrol + a, kontrol + panah kanan untuk mengarahkan kursor ke dekat t=.

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

Perhatikan bahwa ini mempermudah untuk memakukan ekstensi, atau variasi pada nama.

Juga perhatikan bahwa saya membutuhkan ; setelah penugasan variabel, karena var=value cmd hanya menetapkan itu sebagai variabel lingkungan untuk perintah itu, dan tidak mempengaruhi konteks shell.


1
2018-06-21 18:28