Có thể sử dụng các biến tham số shell ($ 1, tầm, $ @) trực tiếp trong CLI không?


9

Đôi khi cần phải mô phỏng và xác minh các biến trên trong các ví dụ nhỏ và sau đó có thể được sao chép ngay lập tức vào một số tập lệnh, v.v.

Tôi đã cố gắng giải quyết bằng cách sử dụng một ví dụ đơn giản theo các cách sau:

(find $1) /tmp
sh -c '(find $1) /tmp'
sh -c "find $1" /tmp
echo '(find $1) /tmp' | sh

và với các kết hợp khác. Cũng đã thử nghiệm bằng cách thêm chỉ thị thông dịch viên shebang #!/bin/sh -x, nhưng không thu được kết quả mong muốn.

Tôi có thể làm điều này đơn giản?


1
(find $1) /tmplà một lỗi cú pháp. Thực tế (any-command) more-argumentslà một lỗi cú pháp. Bạn có thể giải thích khác nhau những gì bạn đang cố gắng làm?
Celada

2
@Celada, nó không phải là một lỗi cú pháp trong vỏ của rcgia đình ( rc, es, akanga...), nơi mà trong trường hợp đó đó là tương đương với find $1 /tmp.
Stéphane Chazelas

Câu trả lời:


15

Đối số đầu tiên sau khi sh -c inline-scriptđi đến $0(cũng được sử dụng cho các thông báo lỗi) và phần còn lại đi vào $1, $2...

$ sh -c 'blah; echo "$0"; echo "$1"' my-inline-script arg
my-inline-script: blah: command not found
my-inline-script
arg

Vậy bạn muốn:

sh -c 'find "$1"' sh /tmp

(vào thời xa xưa, bạn có thể tìm thấy các shtriển khai trong đó đối số đầu tiên đã đi vào $1, vì vậy bạn sẽ làm:

sh -c 'find "$1"' /tmp /tmp

Hoặc là:

sh -c 'shift "$2"; find "$@"' sh 3 2 /tmp1 /tmp2

để giải thích cho cả hai hành vi, nhưng những cái vỏ đó đã biến mất khi POSIX phổ biến và có sẵn công khai).


Nếu bạn muốn đặt $1, $2trong phạm vi cục bộ trong trình bao hiện tại, đó là nơi bạn sử dụng các hàm. Trong vỏ giống như Bourne:

my_func() {
  find "$1"
}
my_func /tmp

Một số shell hỗ trợ các chức năng ẩn danh. Đó là trường hợp của zsh:

(){find "$1"} /tmp

Hoặc es:

@{find $1} /tmp

Để thay đổi các tham số vị trí hiện tại, vĩnh viễn, cú pháp phụ thuộc vào shell. dchirikov đã bao phủ Bourne giống như vỏ (Bourne, Korn, bash, zsh, POSIX, ash, yash...).

Cú pháp là:

set arg1 arg2 ... argn

Tuy nhiên, bạn cần:

set --

Để trống danh sách đó (hoặc shift "$#") và

set -- -foo

để đặt $1thành một cái gì đó bắt đầu bằng -hoặc +, vì vậy, đó là một thói quen tốt để luôn luôn sử dụng set --đặc biệt là khi sử dụng dữ liệu tùy ý như set -- "$@" other-argthêm các đối số vào cuối danh sách tham số vị trí.

Trong shell của cshgia đình ( csh, tcsh), bạn gán cho argvmảng:

set argv=(arg1 arg2)

Trong vỏ của rcgia đình ( rc, es, akanga), để các *mảng:

*=(arg1 arg2)

Mặc dù bạn cũng có thể chỉ định các yếu tố riêng lẻ:

2=arg2

Trong fish, các tham số vị trí đang trong argvmảng chỉ (không $1, $@ở đó):

set argv arg1 arg2

Trong zsh, để tương thích với csh, bạn cũng có thể gán cho argvmảng:

argv=(arg1 arg2)
argv[4]=arg4

Và bạn cũng có thể làm:

5=arg5

Điều đó có nghĩa là bạn cũng có thể làm những việc như:

argv+=(another-arg)

để thêm một đối số vào cuối và:

argv[-1]=()
argv[2]=()

để loại bỏ một đối số từ cuối hoặc giữa, điều mà bạn không thể dễ dàng thực hiện với các shell khác.


7
set --

là những gì bạn cần:

$ set -- aaa bbb ccc
$ echo "$1"
aaa
$ echo "$2"
bbb
$ echo "$3"
ccc
$ echo "$@"
aaa bbb ccc
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.