Làm thế nào để truyền đối số dòng lệnh cho bí danh shell?


288

Làm thế nào để tôi chuyển các đối số dòng lệnh cho một bí danh? Đây là một mẫu:

bí danh mkcd = 'mkdir $ 1; cd $ 1; '

Nhưng trong trường hợp này, $ xx đang được dịch tại bí danh tạo thời gian chứ không phải trong thời gian chạy. Tuy nhiên, tôi đã tạo một cách giải quyết bằng cách sử dụng hàm shell (sau khi googling một chút) như dưới đây:

hàm mkcd () {
  mkdir $ 1
  cd $ 1
}

Chỉ muốn biết liệu có cách nào để tạo bí danh chấp nhận tham số CL hay không.
BTW - Tôi sử dụng 'bash' làm vỏ mặc định của mình.



2
O / T nhưng là một cách thay thế để thực hiện chức năng mkcd, bạn có thể viếtmkdir mydirectoryname && cd $_
moala

Câu trả lời:


174

Bạn đã tìm thấy cách: tạo một hàm thay vì bí danh. Shell C có một cơ chế để thực hiện các đối số cho các bí danh, nhưng bash và shell Korn thì không, bởi vì cơ chế chức năng linh hoạt hơn và cung cấp khả năng tương tự.


Tuy nhiên, bạn không cần các hàm khi tạo bí danh trong .bashrctệp. Ví dụ # tạo một bí danh lấy số cổng của người dùng bí danh phục vụ = "python -m SimpleHTTPServer $ 1" Sau khi thực hiện thay đổi trong tệp .bashrc, hãy đảm bảo bạn nhập lệnh sau. ~ $ source .bashrc Bạn sẽ có thể sử dụng như thế này ~ $ phục vụ 8998
kaizer1v

8
@ kaizer1v, Quan sát của tôi về phiên bản bash CentOS7.3 4.2.46 là đề xuất của bạn không hoạt động như bạn nghĩ. Bởi vì bạn đang sử dụng dấu ngoặc kép, $ 1 thực sự được đánh giá thành một chuỗi rỗng và bí danh thực sự giống như bí danh phục vụ = "python -m SimpleHTTPServer" và do đó, bất cứ điều gì bạn vượt qua sau bí danh đó đều được truyền vào dòng lệnh. Nếu bạn thử bộ này -x; bí danh phục vụ = "python -m SimpleHTTPServer $ 1 &" bạn sẽ thấy lỗi / vấn đề. Cả đối số của bạn và lệnh bí danh đều được chạy dưới dạng các lệnh riêng biệt.
PatS

279

Chỉ để nhắc lại những gì đã được đăng cho các shell khác, trong Bash các tác phẩm sau:

alias blah='function _blah(){ echo "First: $1"; echo "Second: $2"; };_blah'

Chạy như sau:

blah one two

Cung cấp đầu ra dưới đây:

First: one
Second: two

4
Giải pháp tuyệt vời. Một số câu hỏi từ người mới bash: Hàm này có phải được đặt tên bằng dấu gạch dưới (hoặc khác biệt không) hoặc đó chỉ là để đọc? Mục đích của dấu "; _blah" trong việc xác định hàm là gì? Tại sao nó không hoạt động khi sử dụng dấu ngoặc kép thay cho dấu ngoặc đơn ($ 1 không được hiểu chính xác) ngay cả khi làm điều gì đó không yêu cầu dấu ngoặc kép quanh $ 1? Cảm ơn trước cho lời khuyên. Tôi có một giải pháp làm việc nhưng luôn muốn hiểu thêm về lý do tại sao nó hoạt động.
mynameispaulie

4
@mynameispaulie Chức năng có thể được đặt tên bất cứ điều gì. Tôi đã sử dụng tiền tố gạch dưới vì đây là một mẹo phổ biến để giúp ngăn chặn xung đột tên (tức là một chức năng khác có cùng tên)
Thomas Bratt

6
@mynameispaulie Dấu ngoặc kép cho phép Bashthay thế $1$2với các tham số được truyền cho hàm. Trích dẫn duy nhất nói với Bash không làm điều này.
Thomas Bratt

5
Tôi thấy bản sao kết hợp bí danh / chức năng này / dán rất nhiều, nhưng dường như nó không phục vụ bất kỳ mục đích hữu ích nào. Cách tiếp cận tiêu chuẩn sẽ là xác định hàm một lần, với tên lành mạnh và không có bí danh.
tripleee 3/03/2016

16
Tôi không thấy cách này được ưa thích hơnfunction blah(){ echo "First: $1"; echo "Second: $2"; }
René Nyffalanger

57

Bạn không thể trong ksh, nhưng bạn có thể trong csh.

alias mkcd 'mkdir \!^; cd \!^1'

Trong ksh, chức năng là con đường để đi. Nhưng nếu bạn thực sự thực sự muốn sử dụng bí danh:

alias mkcd='_(){ mkdir $1; cd $1; }; _'

Là một lưu ý phụ thú vị, tôi nghĩ rằng lỗ hổng thực thi mã từ xa mà mọi người đang nói đến gần đây liên quan đến việc thực hiện gần như chính xác điều này, nhưng trong một biến môi trường được đặt bởi đầu vào của người dùng thô. openwall.com/lists/oss-securance/2014/09/24/11
Floegipoky

@Floegipoky - Bởi vì nó nằm trong bí danh chứ không phải var env, nên về cơ bản nó khác nhau. Vấn đề của ShellShock là nó chạy khi var env được đặt. Đặt var env được coi là một hoạt động an toàn. Không có tập lệnh nào thực thi khi bí danh trên được đặt, chỉ khi bí danh được chạy.
Sanjaya R

Có lẽ nên chỉ ra rằng đó cshthường không phải là thứ mà một người hiện đại nên muốn sử dụng. Bí danh alir-which-created-a-function-then-executes-that-function là tương đối phổ biến, nhưng không mang lại lợi ích gì cho một chức năng phù hợp như tôi có thể nói. (Dù sao thì hàm cũng nên trích dẫn chính xác đối số của nó.) Downvote.
tripleee

17

Để trích dẫn trang bash man:

Không có cơ chế sử dụng đối số trong văn bản thay thế. Nếu cần đối số, nên sử dụng hàm shell (xem CHỨC NĂNG bên dưới).

Vì vậy, có vẻ như bạn đã trả lời câu hỏi của riêng mình - sử dụng hàm thay vì bí danh



5

Tôi thấy rằng các chức năng không thể được viết trong ~/.cshrctập tin. Ở đây trong bí danh có đối số

ví dụ: các đối số được truyền cho lệnh 'find'

alias fl "find . -name '\!:1'"     
Ex: >fl abc

Trong đó abc là đối số được truyền dưới dạng !: 1


4
Điều đó không hữu ích cho OP, có vỏ mặc định là bash. Và câu trả lời của Sanjaya R đã đề cập đến bí danh csh 4 năm trước.
Keith Thompson

1
Câu trả lời của Sanjaya R không giải thích được điều gì !:1có nghĩa. Tôi đã phải cuộn xuống để thấy rằng đây là đối số. Một câu trả lời tốt không để lại nhiều câu hỏi hơn, ngay cả khi nó không dành cho loại vỏ OP.
searchengine27

4

Cách dễ nhất, là sử dụng chức năng không bí danh. bạn vẫn có thể gọi một chức năng bất cứ lúc nào từ cli. Trong bash, bạn chỉ có thể thêm tên hàm () {lệnh}, nó tải giống như một bí danh.

function mkcd() { mkdir $1; cd $1 ;}

Không chắc chắn về vỏ khác



1

Điều này hoạt động trong ksh:

$ alias -x mkcd="mkdir \$dirname; cd \$dirname;"
$ alias mkcd
mkcd='mkdir $dirname; cd $dirname;'
$ dirname=aaa 
$ pwd
/tmp   
$ mkcd
$ pwd
/tmp/aaa

Tùy chọn "-x" làm cho bí danh "được xuất" - bí danh được hiển thị trong các ô con.

Và lưu ý rằng thực tế là các bí danh được xác định trong một tập lệnh không hiển thị trong tập lệnh đó (vì các bí danh được mở rộng khi tập lệnh được tải, không phải khi một dòng được diễn giải). Điều này có thể được giải quyết bằng cách thực thi một tệp script khác trong cùng một shell (sử dụng dấu chấm).



-2

Đây là một chức năng ví dụ đơn giản sử dụng python. Bạn có thể dính vào ~ / .bashrc
Bạn phải có khoảng trắng sau dấu ngoặc nhọn bên trái đầu tiên
Lệnh python cần được đặt trong dấu ngoặc kép để có được sự thay thế biến đổi
Đừng quên dấu chấm phẩy ở cuối

hàm đếm () {python -c "cho num trong xrange ($ 1): print num";}

$ count 6
0
1
2
3
4
5
$

-5

Một bí danh trống sẽ thực thi các đối số của nó:

alias DEBUG=

12
Tôi thấy bởi đại diện của bạn rằng bạn chưa quen với SO (Stack Overflow). Xin đừng mất tinh thần khi bỏ phiếu cho câu trả lời của bạn. Nó đã được bỏ phiếu xuống vì nó thực sự không trả lời câu hỏi mà OP (Poster gốc) yêu cầu đã trả lời. Treo trong của họ và tiếp tục cố gắng. Ngoài ra khi trả lời, hãy thử đưa vào một ví dụ đơn giản về cách câu trả lời của bạn hoạt động và hiển thị đầu ra. Điều này sẽ giúp người khác thấy câu trả lời của bạn hoạt động như thế nào.
PatS
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.