Làm thế nào tôi có thể ngăn xếp các bí danh shell stack?


12

Trong chế độ mô phỏng của tôi .profile(có nguồn gốc shtừ tôi .zshrc), tôi có đoạn mã sau:

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

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

Tuy nhiên, bí danh thứ hai luôn ghi đè lên đầu tiên:

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

Làm thế nào tôi có thể làm cho nó để gán bí danh thứ hai "kế thừa" nhiệm vụ đầu tiên, để nếu /usr/bin/pacmatictồn tại, bí danh trở thành pacmatic --color auto?

Tôi không phản đối việc sử dụng các hàm thay vì bí danh, nhưng tôi thích nó hơn nếu logic không được thực hiện mỗi lần pacmanđược gọi (tôi muốn pacmatickiểm tra một lần, khi khởi động shell, không phải mỗi lần pacmanchạy). Tôi cũng thích một shtập lệnh có thể di chuyển được, nhưng nếu điều này là không thể, bạn có thể sử dụng zshcú pháp đầy đủ .

(Vâng, tôi biết rằng điều này có thể dễ dàng được giải quyết bằng cách thêm --color autovào pacmaticbí danh. Nhưng tôi muốn thực hiện đúng cách ™.)

Tôi đã thử Google và xem qua các trang, nhưng không có kết quả.


Tôi nghĩ rằng Right Way là sử dụng các chức năng thay vì bí danh. Tôi đã nghe nói rằng họ nhanh hơn bí danh (ít nhất là trong bash) và họ có thể dễ dàng gọi cho nhau.
Wutaz

Câu trả lời:


5

Một shell aliashoạt động khá giống với a #define, tức là xác định lại bí danh shell sẽ ghi đè lên cái trước đó.

Tôi không chắc cái gì sẽ là Right Way TM , nhưng một cách tiếp cận sẽ là sử dụng hàm shell chấp nhận các tham số và sử dụng hàm đó để tạo bí danh. Đoạn mã của bạn có thể được viết lại thành:

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

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

 


Hơn nữa, ngay cả khi bạn đang sử dụng các bí danh khác nhau và đang cố gắng sử dụng một bí danh để xác định cái khác, nó sẽ không hoạt động vì các bí danh không được mở rộng trong chế độ không tương tác theo mặc định. Bạn cần kích hoạt nó bằng cách cài đặt expand_aliases:

shopt -s expand_aliases

Trích dẫn từ hướng dẫn:

   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).

điều này dường như là gần nhất với những gì tôi muốn, nhưng nó không hoạt động. type pacmantrả về pacman is an alias for pacman --color auto, cả trong shchế độ mô phỏng và trong zshchế độ gốc . tuy nhiên, có vẻ như bản chỉnh sửa bạn vừa thực hiện là thứ tôi cần.
strugee

FWIW, tương đương zsh là setopt aliases.
strugee

OP đang sử dụng zsh. Và vỏ dù có vẻ tương tác.
Mikel

6

Thay thế bí danh chỉ được thực hiện khi đọc các dòng từ các nguồn tương tác. Vì vậy, bí danh thứ hai không bị ảnh hưởng bởi cái đầu tiên, do đó thay thế theo nghĩa đen.

Có lẽ một cái gì đó tương tự:

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

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

Điều này sẽ đặt 'pacman' thành giá trị phù hợp, biến env PACMAN không được xuất, do đó, nó sẽ biến mất khi tập lệnh kết thúc và sử dụng "dấu ngoặc kép" sẽ đảm bảo thay thế biến đổi xảy ra khi khai báo bí danh, không cho mỗi lần gọi

Tôi sử dụng một phương pháp tương tự:

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

Về cơ bản, đặt env var PACMAN, kiểm tra nhịp tim trong đường dẫn, nếu tìm thấy, đặt PACMAN, sau đó xác định bí danh.

Hmm, bạn có thể tối ưu hóa thêm một chút ...

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

Taa Daa! Đặt thành 'pacman' nếu PACMAN không được đặt hoặc null, nếu không, được đặt thành giá trị của PACMAN, được đặt thành pacmatic theo dòng 'which'.


Tại sao bí danh chỉ hoạt động cho "nguồn tương tác"?
Mikel

Theo mặc định, bashbạn đúng là không mở rộng bí danh ở chế độ không tương tác, nhưng làm thế nào giống với "nguồn tương tác"?
Mikel

2

Trong zsh, bạn có thể dễ dàng thêm vào bí danh bằng cách sử dụng aliasesmảng kết hợp:

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

Trong các shell khác, bạn cần sử dụng đầu ra của aliaslệnh để tìm hiểu về các bí danh hiện có.

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

Trong khi tôi đưa ra điều này như một khả năng, tôi sẽ sử dụng một biến như đã được đề xuất bởi các câu trả lời khác. Nó rõ ràng hơn và bạn có thể phân biệt giá trị của biến nếu bạn muốn định cấu hình một số thứ khác nhau dựa trên một trong những pacmatichoặc pacmanđang sử dụng.

pacman==pacmatic 2>/dev/null || pacman=pacman
alias pacman='$pacman --color auto'

0

Một phiên bản ngắn cho bí danh thứ 2 sẽ là:

alias pacman=$PACMAN' --color auto'

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 "$@"
)

Bí danh là cho các loài chim.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.