Có những lý do kỹ thuật hợp pháp để muốn một giải pháp tổng quát cho vấn đề bí danh bash không có cơ chế để đưa ra một lập luận tùy ý định vị lại. Một lý do là nếu lệnh bạn muốn thực thi sẽ bị ảnh hưởng bất lợi bởi những thay đổi đối với môi trường do thực thi một chức năng. Trong tất cả các trường hợp khác , các chức năng nên được sử dụng.
Điều gần đây buộc tôi phải thử một giải pháp cho vấn đề này là tôi muốn tạo ra một số lệnh viết tắt để in các định nghĩa về biến và hàm. Vì vậy, tôi đã viết một số chức năng cho mục đích đó. Tuy nhiên, có một số biến nhất định (hoặc có thể) được thay đổi bởi chính hàm gọi. Trong số đó là:
FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV
Lệnh cơ bản mà tôi đã sử dụng (trong một hàm) để in defns biến. ở dạng đầu ra của lệnh set là:
sv () { set | grep --color=never -- "^$1=.*"; }
Ví dụ:
> V=voodoo
sv V
V=voodoo
Vấn đề: Điều này sẽ không in định nghĩa của các biến được đề cập ở trên vì chúng nằm trong ngữ cảnh hiện tại , ví dụ: nếu trong dấu nhắc trình bao tương tác (hoặc không có trong bất kỳ lệnh gọi hàm nào), FUNCNAME không được xác định. Nhưng chức năng của tôi cho tôi biết thông tin sai:
> sv FUNCNAME
FUNCNAME=([0]="sv")
Một giải pháp tôi đã đưa ra đã được đề cập bởi những người khác trong các bài viết khác về chủ đề này. Đối với lệnh cụ thể này để in biến defns., Và chỉ yêu cầu một đối số, tôi đã làm điều này:
alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'
Cung cấp đầu ra chính xác (không có) và trạng thái kết quả (sai):
> asv FUNCNAME
> echo $?
1
Tuy nhiên, tôi vẫn cảm thấy bắt buộc phải tìm một giải pháp phù hợp với số lượng đối số tùy ý.
Một giải pháp chung để vượt qua các lý lẽ tùy tiện cho một lệnh bí danh Bash:
# (I put this code in a file "alias-arg.sh"):
# cmd [arg1 ...] – an experimental command that optionally takes args,
# which are printed as "cmd(arg1 ...)"
#
# Also sets global variable "CMD_DONE" to "true".
#
cmd () { echo "cmd($@)"; declare -g CMD_DONE=true; }
# Now set up an alias "ac2" that passes to cmd two arguments placed
# after the alias, but passes them to cmd with their order reversed:
#
# ac2 cmd_arg2 cmd_arg1 – calls "cmd" as: "cmd cmd_arg1 cmd_arg2"
#
alias ac2='
# Set up cmd to be execed after f() finishes:
#
trap '\''cmd "${CMD_ARGV[1]}" "${CMD_ARGV[0]}"'\'' SIGUSR1;
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# (^This is the actually execed command^)
#
# f [arg0 arg1 ...] – acquires args and sets up trap to run cmd:
f () {
declare -ag CMD_ARGV=("$@"); # array to give args to cmd
kill -SIGUSR1 $$; # this causes cmd to be run
trap SIGUSR1; # unset the trap for SIGUSR1
unset CMD_ARGV; # clean up env...
unset f; # incl. this function!
};
f' # Finally, exec f, which will receive the args following "ac2".
Ví dụ:
> . alias-arg.sh
> ac2 one two
cmd(two one)
>
> # Check to see that command run via trap affects this environment:
> asv CMD_DONE
CMD_DONE=true
Một điều thú vị về giải pháp này là tất cả các thủ thuật đặc biệt được sử dụng để xử lý các tham số vị trí (đối số) cho các lệnh sẽ hoạt động khi soạn thảo lệnh bị bẫy. Sự khác biệt duy nhất là cú pháp mảng phải được sử dụng.
Ví dụ,
Nếu bạn muốn "$ @", hãy sử dụng "$ {CMD_ARGV [@]}".
Nếu bạn muốn "$ #", hãy sử dụng "$ {# CMD_ARGV [@]}".
Vân vân.