Cách phổ biến để làm điều đó được gán các đối số cho các biến cục bộ trong hàm, ví dụ:
copy() {
local from=${1}
local to=${2}
# ...
}
Một giải pháp khác có thể là phân tích cú pháp tùy chọn getopt kiểu.
copy() {
local arg from to
while getopts 'f:t:' arg
do
case ${arg} in
f) from=${OPTARG};;
t) to=${OPTARG};;
*) return 1 # illegal option
esac
done
}
copy -f /tmp/a -t /tmp/b
Đáng buồn thay, bash không thể xử lý tùy chọn dài mà sẽ thể dễ đọc hơn, ví dụ:
copy --from /tmp/a --to /tmp/b
Cho rằng, bạn có cần phải sử dụng các chương trình bên ngoài getopt
(mà Tôi nghĩ rằng chỉ hỗ trợ tùy chọn dài trên các hệ thống GNU) hoặc thực hiện trình phân tích cú pháp tùy chọn dài bằng tay, tức là:
copy() {
local from to
while [[ ${1} ]]; do
case "${1}" in
--from)
from=${2}
shift
;;
--to)
to=${2}
shift
;;
*)
echo "Unknown parameter: ${1}" >&2
return 1
esac
if ! shift; then
echo 'Missing parameter argument.' >&2
return 1
fi
done
}
copy --from /tmp/a --to /tmp/b
.210
Xem thêm: using getopts in bash shell script to get long and short command line options
Bạn cũng có thể được lười biếng, và chỉ cần vượt qua 'biến' như các đối số cho hàm, ví dụ::
copy() {
local "${@}"
# ...
}
copy from=/tmp/a to=/tmp/b
và bạn sẽ có ${from}
và ${to}
trong hàm như biến cục bộ.
Chỉ cần lưu ý rằng vấn đề tương tự như dưới đây sẽ áp dụng - nếu một biến cụ thể không được chuyển, nó sẽ được kế thừa từ môi trường mẹ. Bạn có thể muốn thêm một 'dòng an toàn' như:
copy() {
local from to # reset first
local "${@}"
# ...
}
để đảm bảo rằng ${from}
và ${to}
sẽ unset khi không được thông qua.
Và nếu có điều gì rất xấu là quan tâm của bạn, bạn cũng có thể gán các đối số là các biến toàn cục khi gọi chức năng, ví dụ:
from=/tmp/a to=/tmp/b copy
Sau đó, bạn có thể chỉ cần sử dụng ${from}
và ${to}
trong hàm copy()
. Chỉ cần lưu ý rằng bạn nên luôn luôn chuyển tất cả các thông số. Nếu không, một biến ngẫu nhiên có thể bị rò rỉ vào hàm.
from= to=/tmp/b copy # safe
to=/tmp/b copy # unsafe: ${from} may be declared elsewhere
Nếu bạn có bash 4.1 (tôi nghĩ), bạn cũng có thể thử sử dụng các mảng kết hợp. Nó sẽ cho phép bạn vượt qua các đối số được đặt tên nhưng nó sẽ trở nên xấu xí. Một cái gì đó như:
args=([from]=/tmp/a [to]=/tmp/b)
copy args
Và sau đó tại copy()
, bạn cần phải grab the array.
Sự khác nhau giữa việc sử dụng '$ 1' so với' $ ARG1' là gì? –
@JonLin: Tôi có thể sử dụng tên trực quan hơn, thay vì $ 1, $ 2. Các con số rất khó hiểu. – Bhushan
Bạn có thực sự yêu cầu bảy tham số bắt buộc không? Một cách tiếp cận phổ biến sẽ là biến càng nhiều càng tốt thành các tùy chọn, và cung cấp một giá trị mặc định, nơi nó có ý nghĩa. Nó làm cho kịch bản của bạn dễ sử dụng hơn nhiều nếu bạn không phải ghi nhớ một thứ tự vị trí cụ thể cho một số lượng lớn các đối số, ngay cả khi hầu hết người dùng sẽ ghi đè các giá trị mặc định hầu hết thời gian. – tripleee