Đầu tiên, lưu ý rằng $@
không có trích dẫn sẽ không có ý nghĩa và không nên được sử dụng. $@
chỉ nên được sử dụng trích dẫn ( "$@"
) và trong bối cảnh danh sách.
for i in "$@"
đủ điều kiện làm bối cảnh danh sách, nhưng ở đây, để lặp lại các tham số vị trí, dạng chính tắc, di động nhất và đơn giản hơn là:
for i
do something with "$i"
done
Bây giờ, để lặp lại các phần tử bắt đầu từ phần thứ hai, cách thức hợp quy và di động nhất là sử dụng shift
:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Sau đó shift
, những gì $1
đã từng bị xóa khỏi danh sách (nhưng chúng tôi đã lưu nó vào $first_arg
) và những gì trước $2
đây đã có trong đó $1
. Các tham số vị trí đã được dịch chuyển 1
vị trí sang trái (sử dụng shift 2
để dịch chuyển 2 ...). Về cơ bản, vòng lặp của chúng ta đang lặp từ những gì từng là đối số thứ hai đến cuối cùng.
Với bash
(và zsh
và ksh93
, nhưng đó của nó), một sự thay thế là để làm:
for i in "${@:2}"
do something with "$i"
done
Nhưng lưu ý rằng đó không phải là sh
cú pháp chuẩn nên không được sử dụng trong tập lệnh bắt đầu bằng #! /bin/sh -
.
Trong zsh
hoặc yash
, bạn cũng có thể làm:
for i in "${@[3,-3]}"
do something with "$i"
done
để lặp từ đối số thứ 3 đến thứ 3 cuối cùng.
Trong zsh
, $@
còn được gọi là $argv
mảng. Vì vậy, để các phần tử pop từ đầu hoặc cuối của mảng, bạn cũng có thể làm:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shift
Cũng có thể được viết 1=()
trong zsh
)
Trong bash
, bạn chỉ có thể gán cho các $@
phần tử có set
nội dung, vì vậy để bật 3 phần tử ở cuối, đó sẽ là một cái gì đó như:
set -- "${@:1:$#-3}"
Và để lặp từ thứ 3 đến thứ 3 cuối cùng:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIXly, để bật 3 yếu tố cuối cùng "$@"
, bạn cần sử dụng một vòng lặp:
n=$(($# - 3))
for arg do
[ "$n" -gt 0 ] && set -- "$@" "$arg"
shift
n=$((n - 1))
done
for ((i=2; i<=$#; i++)); do something with "${!i}"; done