2010-04-29 32 views
59

Tôi đang cố gắng viết một hàm trong bash sẽ truy cập các đối số dòng lệnh của tập lệnh, nhưng chúng được thay thế bằng các đối số vị trí cho hàm. Có cách nào để chức năng truy cập các đối số dòng lệnh nếu chúng không được truyền một cách rõ ràng không?Trong Bash, làm thế nào để bạn truy cập các đối số dòng lệnh bên trong một hàm?

# Demo function 
function stuff { 
    echo $0 $* 
} 

# Echo's the name of the script, but no command line arguments 
stuff 

# Echo's everything I want, but trying to avoid 
stuff $* 
+3

Tôi loại bối rối, bạn muốn args với ra đi họ ? –

+2

Có, vấn đề là để có được quá các đối số dòng lệnh từ bên trong một hàm mà không cần chuyển chúng thành các đối số chức năng. Nó phải làm với một tình huống xử lý lỗi mà tôi muốn xử lý lỗi dựa trên các đối số dòng lệnh độc lập với các đối số được truyền vào hàm. – DonGar

Trả lời

30

Việc đọc sách hướng dẫn bash của tôi cho biết nội dung này được ghi lại trong BASH_ARGV, mặc dù nó nói về "chồng" rất nhiều.

#!/bin/bash 

function argv { 
    for a in ${BASH_ARGV[*]} ; do 
     echo -n "$a " 
    done 
    echo 
} 

function f { 
    echo f $1 $2 $3 
    echo -n f ; argv 
} 

function g { 
    echo g $1 $2 $3 
    echo -n g; argv 
    f 
} 

f boo bar baz 
g goo gar gaz 

Lưu trong f.sh

$ ./f.sh arg0 arg1 arg2 
f boo bar baz 
farg2 arg1 arg0 
g goo gar gaz 
garg2 arg1 arg0 
f 
farg2 arg1 arg0 
+4

Lưu ý rằng việc sửa đổi mảng như vậy sẽ khiến cho các arg được xếp theo thứ tự ngược lại từ dòng lệnh. –

8
#!/usr/bin/env bash 

echo name of script is $0 
echo first argument is $1 
echo second argument is $2 
echo seventeenth argument is $17 
echo number of arguments is $# 

Edit: xin vui lòng xem nhận xét của tôi về câu hỏi

64

Nếu bạn muốn có lập luận C phong cách của bạn (mảng các đối số + số lượng các đối số), bạn có thể sử dụng $ @ và $ #.

$ # cung cấp cho bạn số lượng đối số. $ @ cung cấp cho bạn tất cả các đối số. bạn có thể tắt chức năng này vào một mảng bằng args=("[email protected]")

Vì vậy, ví dụ:

args=("[email protected]") 
echo $# arguments passed 
echo ${args[0]} ${args[1]} ${args[2]} 

Note thate đây ${args[0]} thực sự là đối số 1 và không phải là tên của kịch bản của bạn.

+1

Điều này không giải quyết được câu hỏi - nó hỏi về việc truyền các đối số dòng lệnh cùng với một hàm hệ vỏ. – Cascabel

+5

@Jefromi, thực sự, nó trả lời câu hỏi một cách hoàn hảo. Bạn có thể sử dụng mảng 'args' từ bên trong một hàm, nếu bạn khởi tạo nó trước như mô tả. – vadipp

+1

Tôi thấy điều này sạch hơn nhiều so với lặp lại trên args. –

5
# Save the script arguments 
SCRIPT_NAME=$0 
ARG_1=$1 
ARGS_ALL=$* 

function stuff { 
    # use script args via the variables you saved 
    # or the function args via $ 
    echo $0 $* 
} 


# Call the function with arguments 
stuff 1 2 3 4 
14

Nhận xét của Ravi về bản chất là câu trả lời. Các hàm lấy đối số riêng của chúng. Nếu bạn muốn chúng giống như các đối số dòng lệnh, bạn phải truyền chúng vào. Nếu không, bạn rõ ràng đang gọi một hàm không có đối số.

Điều đó nói rằng, bạn có thể nếu bạn muốn lưu trữ các đối số dòng lệnh trong một mảng toàn cầu để sử dụng trong phạm vi chức năng khác:

my_function() { 
    echo "stored arguments:" 
    for arg in "${commandline_args[@]}"; do 
     echo " $arg" 
    done 
} 

commandline_args=("[email protected]") 

my_function 

Bạn cần phải truy cập vào các đối số dòng lệnh thông qua các biến commandline_args, không [email protected], $1, $2, v.v. nhưng chúng khả dụng. Tôi không biết bất kỳ cách nào để gán trực tiếp cho mảng đối số, nhưng nếu ai đó biết một, hãy khai sáng cho tôi!

Ngoài ra, hãy lưu ý cách tôi đã sử dụng và được trích dẫn [email protected] - đây là cách bạn đảm bảo các ký tự đặc biệt (khoảng trắng) không bị bỏ ẩn.

2

Bạn có thể sử dụng từ khoá thay đổi (điều hành?) Để lặp qua chúng. Ví dụ:

#!/bin/bash 
function print() 
{ 
    while [ $# -gt 0 ] 
    do 
     echo $1; 
     shift 1; 
    done 
} 
print $*; 
2

Người ta có thể làm điều đó như thế này cũng

#!/bin/bash 
# script_name function_test.sh 
function argument(){ 
for i in [email protected];do 
    echo $i 
done; 
} 
argument [email protected] 

Bây giờ gọi kịch bản của bạn như

./function_test.sh argument1 argument2 
Các vấn đề liên quan