Bagaimana saya bisa "menumpuk" shell alias?

12

Dalam .profile(bersumber dalam shmode emulasi dari saya .zshrc), saya memiliki cuplikan berikut:

if [ -f /usr/bin/pacmatic ]; then
    alias pacman=pacmatic
fi

# Colorized Pacman output
alias pacman="pacman --color auto"

Namun, alias kedua selalu menimpa yang pertama:

% type pacman
pacman is an alias for pacman --color auto

Bagaimana saya bisa membuatnya sehingga tugas alias kedua "mewarisi" tugas pertama, sehingga jika /usr/bin/pacmaticada, alias menjadi pacmatic --color auto?

Saya tidak menolak untuk menggunakan fungsi alih-alih alias, tapi saya lebih suka jika logika tidak dilakukan setiap kali pacmandipanggil (saya ingin pacmaticdiperiksa sekali, pada shell startup, tidak setiap kali pacmandijalankan). Saya juga lebih suka shskrip -portable, tetapi jika ini tidak memungkinkan, Anda dapat menggunakan zshsintaks lengkap .

(Ya, aku menyadari bahwa ini bisa dengan mudah diselesaikan dengan menambahkan --color autoke pacmaticalias. Tapi aku ingin melakukannya Way Kanan ™.)

Saya sudah mencoba Googling dan melihat-lihat halaman manual, tetapi tidak berhasil.

strugee
sumber
Saya pikir Right Way adalah menggunakan fungsi alih-alih alias. Saya pernah mendengar bahwa mereka lebih cepat daripada alias (setidaknya dalam bash), dan mereka dapat dengan mudah saling memanggil.
Wutaz

Jawaban:

5

Shell aliasberperilaku sangat mirip dengan #define, yaitu mendefinisikan kembali alias shell akan menimpa yang sebelumnya.

Saya tidak yakin apa yang akan menjadi Right Way TM , tetapi satu pendekatan akan menggunakan fungsi shell yang menerima parameter dan menggunakannya untuk membuat alias. Cuplikan kode Anda dapat ditulis ulang sebagai:

if [ -f /usr/bin/pacmatic ]; then
    pacman() { pacmatic "$@"; }
fi

# Colorized Pacman output
alias pacman="pacman --color auto"

 


Selain itu, bahkan jika Anda menggunakan alias berbeda dan mencoba menggunakan satu untuk mendefinisikan yang lain, itu tidak akan berfungsi karena alias tidak diperluas dalam mode non-interaktif secara default. Anda harus mengaktifkannya dengan mengatur expand_aliases:

shopt -s expand_aliases

Mengutip dari manual:

   Aliases are not expanded when the shell is not interactive, unless  the
   expand_aliases  shell option is set using shopt (see the description of
   shopt under SHELL BUILTIN COMMANDS below).
devnull
sumber
ini tampaknya paling dekat dengan apa yang saya inginkan, tetapi tidak berhasil. type pacmankembali pacman is an alias for pacman --color auto, baik dalam shmode emulasi dan dalam zshmode asli . Namun, sepertinya edit yang baru saja Anda buat adalah yang saya butuhkan.
strugee
FWIW, setara dengan zsh adalah setopt aliases.
strugee
OP menggunakan zsh. Dan cangkang itu tampaknya bersifat interaktif.
Mikel
6

Substitusi alias hanya dilakukan ketika membaca baris dari sumber interaktif. Jadi alias kedua tidak terpengaruh oleh yang pertama, maka dari itu penggantian literal.

Mungkin sesuatu yang serupa:

PACMAN=pacman
if [ -f /usr/bin/pacmatic ]; then
    PACMAN=pacmatic
fi

# Colorized Pacman output
alias pacman="${PACMAN} --color auto"

Ini akan mengatur 'pacman' ke nilai yang tepat, variabel env PACMAN tidak diekspor, jadi itu akan hilang ketika skrip selesai, dan menggunakan "tanda kutip ganda" akan memastikan bahwa substitusi variabel terjadi pada deklarasi alias, tidak untuk setiap doa.

Saya menggunakan metode serupa:

PACMAN=pacman
which pacmatic &>/dev/null && PACMAN=pacmatic
alias pacman="${PACMAN} --color auto"

Pada dasarnya, atur env var PACMAN, uji untuk jalur pacmatic, jika ditemukan, atur PACMAN, lalu tentukan alias.

Hmm, Anda bisa mengoptimalkan sedikit lagi ...

which pacmatic &>/dev/null && PACMAN=pacmatic
alias pacman="${PACMAN:-pacman} --color auto"

Taa Daa! Setel ke 'pacman' jika PACMAN tidak disetel atau null, jika tidak, setel ke nilai PACMAN, atur ke pacmatic oleh baris 'which'.

lornix
sumber
Mengapa alias hanya berfungsi untuk "sumber interaktif"?
Mikel
Anda benar bahwa secara default, bashtidak memperluas alias dalam mode non-interaktif, tetapi bagaimana itu sama dengan "sumber interaktif"?
Mikel
2

Di zsh, Anda dapat dengan mudah menambahkan alias dengan menggunakan aliasesarray asosiatif:

alias pacman="${aliases[pacman]-pacman} --color auto"

Di shell lain, Anda perlu menggunakan output dari aliasperintah untuk mencari tahu tentang alias yang ada.

current_pacman_alias=$(alias pacman 2>/dev/null)
alias pacman="${current_pacman_alias:-pacman} --color auto"

Sementara saya menawarkan ini sebagai kemungkinan, saya akan menggunakan variabel yang sudah disarankan oleh jawaban lain. Ini lebih jelas, dan Anda dapat membedakan nilai variabel jika Anda ingin mengonfigurasi beberapa hal secara berbeda berdasarkan yang mana dari salah satu pacmaticatau pacmansedang digunakan.

pacman==pacmatic 2>/dev/null || pacman=pacman
alias pacman='$pacman --color auto'
Gilles 'SANGAT berhenti menjadi jahat'
sumber
0

Versi singkat untuk alias ke-2 adalah:

alias pacman=$PACMAN' --color auto'
Michael Durrant
sumber
0
pacman() ( def_args="--color auto" bin=
    [ -x ${bin:=/usr/bin/pacmatic} ] || bin=
    [ -x ${bin:=/usr/bin/pacman} ] || bin= 
    ${bin:?WHERE THE HELL IS PACMAN????} \
        $def_args "$@"
)

Alias ​​adalah untuk burung.

mikeserv
sumber