Bisakah saya meneruskan argumen ke perintah alias?

19

Saya ingin tahu apakah saya bisa menyampaikan argumen dengan perintah alias.

sebagai contoh:

alias d="dmesg|grep -iw usb|tail -5" 

Sekarang dakan mencetak 5 baris terakhir. Jika saya ingin menggunakan d untuk mencetak jumlah baris yang berbeda, saya harus membuat perubahan pada perintah deklarasi alias dlagi.

Apakah ada cara saya dapat memodifikasi deklarasi alias sehingga saya tidak perlu mengetik ulang deklarasi untuk mengubah jumlah baris. Suka menggabungkan melewati jumlah baris sebagai argumen sambil mendeklarasikan alias untuk d? Atau adakah metode lain untuk menyelesaikan ini?

srk_cb
sumber
Dalam (t) csh, "\! *" Referensi argumen ke alias (garis miring terbalik hanya untuk menghindari tanda seru yang biasanya berarti "sejarah"), dan Anda bahkan dapat merujuk argumen individual, meskipun saya tidak ingat caranya. Jadi mungkin "tail -n \! *" Atau sesuatu (saya tidak berpikir \! * Akan bekerja dengan tanda minus segera sebelum itu). Namun, tidak yakin apakah ini akan berhasil di (ba) sh.
barrycarter

Jawaban:

20

Alias ​​tidak mengambil argumen. Dengan alias seperti alias foo='bar $1', maka $1akan diperluas oleh shell ke argumen pertama shell (yang kemungkinan tidak ada) saat alias dijalankan.

Jadi: Gunakan fungsi , sebagai gantinya.

d () {
  num=${1:-5}
  dmesg |grep -iw usb|tail -$num
}

num=${1:-5} menggunakan argumen pertama, dengan nilai default 5 jika tidak disediakan.

Maka Anda dapat melakukan:

$ d
# prints 5 lines
$ d 10
# prints 10 lines

Atau, jika Anda mengubah sedikit opsi yang Anda gunakan:

alias d="dmesg|grep -iw usb|tail -n 5"

Kemudian Anda dapat melewati -nopsi tambahan :

$ d
# prints 5 lines
$ d -n 10
# prints 10 lines

Jika beberapa -nopsi ditentukan tail, hanya yang terakhir yang digunakan.

muru
sumber
Untuk fungsional menantang seperti saya :) mungkin akan membantu untuk negara secara singkat di mana untuk menempatkan fungsi ... yaitu ~/.bashrcatau rc.localatau di mana pun?
WinEunuuchs2Unix
@ WinEunuuchs2Unix di mana pun alias akan diletakkan.
muru
5

Anda harus memiliki fungsi untuk ini seperti yang dijelaskan dalam SO dan di sini . Coba yang berikut ini:

foo() { /path/to/command "$@" ;}

dan panggil foodengan:

foo arg1 arg2 arg3
Ron
sumber
4

Mengatasi keterbatasan alias dengan perintah grup dan di sini-string

Alias ​​tidak dapat mengambil argumen, tetapi kita dapat "mensimulasikan" itu. Ambil contoh jawaban saya untuk pertanyaan ini .

alias mkcd='{ IFS= read -r d && mkdir "$d" && cd "$d"; } <<<'

Poin-poin penting yang terjadi di sini:

  • kami menggunakan readbawaan untuk membaca string ke dalam variabel d. Karena kami ingin membaca string lengkap termasuk karakter kosong (baris baru, tab, spasi), kami menggunakan IFS=dan menonaktifkan backslash lolos dengan -r.
  • <<<yang ada di sini-operator string memungkinkan kita untuk mengarahkan string apa pun yang kita berikan sebagai argumen ke mkcdalias; penggunaannya akan sepertimkcd "some directory"
  • banyak perintah dalam alias digabungkan dan dieksekusi dalam shell saat ini menggunakan { list; }struktur (yang dikenal sebagai group commanddalam bashmanual). Perhatikan bahwa memimpin ruang setelah {dan ;daftar perintah individu diperlukan.

Dalam contoh spesifik Anda, kami dapat melakukan:

alias d='{ IFS= read -r n; dmesg | grep -iw "usb" | tail -n ${n:-5};} <<<'

Kami juga dapat menggunakan pemisahan kata untuk menyimpan argumen yang dipisahkan oleh ruang:

bash-4.3$ { read -r a1 a2; echo "$a1"; echo "$a2";}  <<< "arg1 arg2"
arg1
arg2

Atau kita bisa menggunakan array untuk memberikan beberapa argumen:

bash-4.3$ { read -a arr; echo "${arr[1]}"; echo "${arr[0]}";}  <<< "arg1 arg2"
arg2
arg1

Tetapi apakah ini pendekatan yang bagus?

Belum tentu. Masalah dengan pendekatan tersebut adalah sangat spesifik - argumen tidak dapat dikutip dengan mudah yang berarti kita hanya dapat memiliki argumen tanpa spasi.

bash-4.3$ { read -r a1 a2; echo "$a1"; echo "$a2";}  <<< "'arg1 with space' arg2"
'arg1
with space' arg2

Ini tentu saja bukan sesuatu yang akan digunakan secara luas, hanya karena di dunia nyata kita harus berurusan dengan argumen yang kompleks, jadi pendekatan ini tidak cukup praktis. Fungsinya jauh lebih fleksibel. Dan kebutuhan untuk mengutip string args menjadi cepat menjengkelkan.

Terlepas dari keterbatasannya, ini bekerja dengan string sederhana sebagai argumen di mana kita dapat memisahkan kata, sehingga sebagian memungkinkan kita untuk memberikan argumen kepada alias.

Sergiy Kolodyazhnyy
sumber