Bash 스크립트에서 인수를 반복하는 방법
셸/배시 스크립트를 만들고 싶은 복잡한 명령어가 있습니다.을 그 ... ... 쓸 수 .의 관점에서 쓸 수 있다.$1
★★★★★★★★★★★★★★★★★★:
foo $1 args -o $1.ext
스크립트에 여러 개의 입력 이름을 전달할 수 있기를 원합니다.어떻게 하면 좋을까요?
그리고 물론 파일명에 공백이 있는 파일명은 취급하고 싶습니다.
"$@"
모든 인수를 나타냅니다.
for var in "$@"
do
echo "$var"
done
이것은 각 인수에 대해 반복되며 다른 행으로 출력됩니다.$@는 $*와 같이 동작합니다.단, 따옴표로 둘러싸인 인수는 공백이 있는 경우 올바르게 분할됩니다.
sh test.sh 1 2 '3 4'
1
2
3 4
로버트 갬블의 간결한 대답은 그 질문을 직접적으로 다룬다.이것은 공백이 포함된 파일 이름에 대한 몇 가지 문제를 증폭시킵니다.
참고 항목: /bin/sh의 ${1:+"$@"}
본본: : "$@"
$*
을 사용하다그 이유는"$@"
는 인수에 되어 있는 하며, 「스페이스」와 같이 합니다.$*
「」가 되는 경우도 있습니다."$*"
★★★★★★★★★★★★★★★★★★★」"$@"
(항상 그렇지는 않지만) 같은 장소에서 동작합니다. 없음, 옴옴 、$@
★★★★★★★★★★★★★★★★★」$*
는 동등합니다(그리고 거의 항상 틀립니다).
그럼, 다른 점은 무엇일까요?$*
,$@
,"$*"
, , , , 입니다."$@"
모두 '쉘에 대한 모든 인수'와 관련이 있지만 다른 작업을 수행합니다.둘러싸지 않은 경우, 「」$*
★★★★★★★★★★★★★★★★★」$@
'이들은 각 '단어'(비 공백의 시퀀스)를 별도의 인수로 취급한다. 인용된 는 상당히 인용된 형식은 다르다."$*"
된 단일단, "는 공백으로 구분된 문자열로 취급합니다."$@"
는 명령줄에서 지정된 인수와 거의 동일하게 처리합니다. "$@"
인수가 에는 전혀 되지 않습니다."$*"
을 사용하다그렇습니다만, 인식하기 어려울 수도 있습니다만, 차이가 있습니다. 명령어(「」)의 .al
.
두 번째 논제: 공백으로 인수를 처리한 후 다른 명령어로 전달해야 하는 경우 보조할 비표준 툴이 필요할 수 있습니다(또는 어레이를 신중하게 사용해야 합니다)."${array[@]}"
"$@"
예:
$ mkdir "my dir" anotherdir
$ ls
anotherdir my dir
$ cp /dev/null "my dir/my file"
$ cp /dev/null "anotherdir/myfile"
$ ls -Fltr
total 0
drwxr-xr-x 3 jleffler staff 102 Nov 1 14:55 my dir/
drwxr-xr-x 3 jleffler staff 102 Nov 1 14:55 anotherdir/
$ ls -Fltr *
my dir:
total 0
-rw-r--r-- 1 jleffler staff 0 Nov 1 14:55 my file
anotherdir:
total 0
-rw-r--r-- 1 jleffler staff 0 Nov 1 14:55 myfile
$ ls -Fltr "./my dir" "./anotherdir"
./my dir:
total 0
-rw-r--r-- 1 jleffler staff 0 Nov 1 14:55 my file
./anotherdir:
total 0
-rw-r--r-- 1 jleffler staff 0 Nov 1 14:55 myfile
$ var='"./my dir" "./anotherdir"' && echo $var
"./my dir" "./anotherdir"
$ ls -Fltr $var
ls: "./anotherdir": No such file or directory
ls: "./my: No such file or directory
ls: dir": No such file or directory
$
、 ? 、 이 변수를하지 않습니다셸이 변수를 확장하기 전에 따옴표를 처리하기 때문에 작동하지 않습니다.이 '따옴표'에 $var
, 을.eval
:
$ eval ls -Fltr $var
./my dir:
total 0
-rw-r--r-- 1 jleffler staff 0 Nov 1 14:55 my file
./anotherdir:
total 0
-rw-r--r-- 1 jleffler staff 0 Nov 1 14:55 myfile
$
있다'고요.He said, "Don't do this!"
( 「 」 、 「 」 、 「 」
$ cp /dev/null "He said, \"Don't do this!\""
$ ls
He said, "Don't do this!" anotherdir my dir
$ ls -l
total 0
-rw-r--r-- 1 jleffler staff 0 Nov 1 15:54 He said, "Don't do this!"
drwxr-xr-x 3 jleffler staff 102 Nov 1 14:55 anotherdir
drwxr-xr-x 3 jleffler staff 102 Nov 1 14:55 my dir
$
셸(모두)은 이러한 작업을 처리하는 것을 특별히 쉽게 하지 않기 때문에 (재밌게도) 많은 Unix 프로그램이 이러한 작업을 잘 처리하지 못합니다.UNIX에서는, 컴포넌트)에는, 및 NUL UNIX 「」, 「」( 「」)를 의 문자를 할 수 .'\0'
그러나 셸은 경로 이름 어디에도 공백, 줄 바꿈 또는 탭을 사용하지 않도록 강력히 권장하고 있습니다.또한 표준 Unix 파일 이름에 공백 등이 포함되지 않는 것도 이 때문입니다.
공백이나 귀찮은 문자를 포함한 파일명을 취급할 때는 매우 주의가 필요합니다만, UNIX에 표준이 아닌 프로그램이 필요하다는 것을 오래전에 알았습니다.는 그것을 나는그 it it라고 부른다.escape
1.(버전 1.1 1989-08-23)의 )T16:01:45Z).
를 들면, 이런 입니다.escape
SCCS - SCCS - SCCS - SCCS - SCCS 。 일을 에 하는 입니다.delta
(체크인을 생각할 것) 및get
(체크 아웃을 생각해 주세요).다양한 주장, 특히-y
(변경한 이유)에는 공백과 줄바꿈이 포함됩니다. 이후부터는 합니다.$(cmd ...)
및 ""는 .#!/bin/sh
맨 앞줄에
: "@(#)$Id: delget.sh,v 1.8 1992/12/29 10:46:21 jl Exp $"
#
# Delta and get files
# Uses escape to allow for all weird combinations of quotes in arguments
case `basename $0 .sh` in
deledit) eflag="-e";;
esac
sflag="-s"
for arg in "$@"
do
case "$arg" in
-r*) gargs="$gargs `escape \"$arg\"`"
dargs="$dargs `escape \"$arg\"`"
;;
-e) gargs="$gargs `escape \"$arg\"`"
sflag=""
eflag=""
;;
-*) dargs="$dargs `escape \"$arg\"`"
;;
*) gargs="$gargs `escape \"$arg\"`"
dargs="$dargs `escape \"$arg\"`"
;;
esac
done
eval delta "$dargs" && eval get $eflag $sflag "$gargs"
을 잘 것 은 (탈옥은) . - 탈옥은 필요 없습니다.-e
들어 중 입니다.escape
escape
은 단순히 할 뿐이며, 를 들어 '인수'나 '인수'와 같이 출력합니다.echo
됩니다.eval
의 입니다.eval
셸 , 이은 모모 execution execution execution of of of of of of of of of of of의 가 있었습니다.또한 이 프로그램의 출력을 회피할 필요가 있습니다.escape
를 참조해 주세요.
$ escape $var
'"./my' 'dir"' '"./anotherdir"'
$ escape "$var"
'"./my dir" "./anotherdir"'
$ escape x y z
x y z
$
다른 프로그램이 있는데al
는 인수를 한 줄에1개씩 나열하고 있습니다(더 오래된 버전 1.1 1987-01-27T14:35:49).스크립트를 디버깅할 때 가장 유용합니다.이 스크립트는 명령줄에 삽입하여 실제로 어떤 인수가 명령어에 전달되는지 확인할 수 있습니다.
$ echo "$var"
"./my dir" "./anotherdir"
$ al $var
"./my
dir"
"./anotherdir"
$ al "$var"
"./my dir" "./anotherdir"
$
[추가사항: 이제 다양한 차이점을 보여 줍니다."$@"
표기의 예를 다음에 나타냅니다.
$ cat xx.sh
set -x
al $@
al $*
al "$*"
al "$@"
$ sh xx.sh * */*
+ al He said, '"Don'\''t' do 'this!"' anotherdir my dir xx.sh anotherdir/myfile my dir/my file
He
said,
"Don't
do
this!"
anotherdir
my
dir
xx.sh
anotherdir/myfile
my
dir/my
file
+ al He said, '"Don'\''t' do 'this!"' anotherdir my dir xx.sh anotherdir/myfile my dir/my file
He
said,
"Don't
do
this!"
anotherdir
my
dir
xx.sh
anotherdir/myfile
my
dir/my
file
+ al 'He said, "Don'\''t do this!" anotherdir my dir xx.sh anotherdir/myfile my dir/my file'
He said, "Don't do this!" anotherdir my dir xx.sh anotherdir/myfile my dir/my file
+ al 'He said, "Don'\''t do this!"' anotherdir 'my dir' xx.sh anotherdir/myfile 'my dir/my file'
He said, "Don't do this!"
anotherdir
my dir
xx.sh
anotherdir/myfile
my dir/my file
$
을 유지하는 것은 .*
★★★★★★★★★★★★★★★★★」*/*
커맨드 라인에 표시됩니다.또한 다음 명령을 사용하여 셸의 '명령줄 인수'를 변경할 수 있습니다.
set -- -new -opt and "arg with space"
4가지 선택지 '4가지 를 할 수 있습니다-new
, ' , '-opt
, ' , 'and
, , , ' "arg with space
'
음, 꽤 긴 답변이네요 - 아마도 대리인이 더 나은 용어일 겁니다.소스 코드escape
도트 성「 」의 .al
매우 간단합니다.
#include <stdio.h>
int main(int argc, char **argv)
{
while (*++argv != 0)
puts(*argv);
return(0);
}
그게 다예요.이것은 에 상당합니다.test.sh
로 셸로 쓸 수 단, Robert Gamble을 썼을 는 셸 버전에는 al
를 참조해 주세요.
, 「 」, 「 」, 「 」라고 쓸 수도 .al
단순한 셸 스크립트로 사용합니다.
[ $# != 0 ] && printf "%s\n" "$@"
인수 없이 전달해도 출력이 생성되지 않도록 조건이 필요합니다.printf
명령어는 format string 인수만 사용하여 공백 행을 생성하지만 C 프로그램은 아무것도 생성하지 않습니다.
Robert에서 합니다.sh
만만 you 수 .한층 더 심플하게(휴대용으로) 할 수 있습니다.
for i in "$@"
는 다음과 같습니다.
for i
즉, 당신은 아무것도 필요 없어요!
$
: is "sis "command prompt") :
$ set a b "spaces here" d
$ for i; do echo "$i"; done
a
b
spaces here
d
$ for i in "$@"; do echo "$i"; done
a
b
spaces here
d
저는 이것에 대해 Kernighan과 Pike의 Unix Programming Environment에서 처음 읽었습니다.
»bash
,help for
음음 츠키
for NAME [in WORDS ... ;] do COMMANDS; done
if
'in WORDS ...;'
, 없다.'in "$@"'
상정하고 있습니다.
라면 '어디로 하다'를 .shift
인수 목록을 큐처럼 처리합니다. ★★shift
첫 번째 인수가 삭제되고 나머지 각 인수의 인덱스가 감소합니다.
#this prints all arguments
while test $# -gt 0
do
echo "$1"
shift
done
예를 들어 모든 요소를 반복하지 않는 경우 어레이 요소로 액세스할 수도 있습니다.
argc=$#
argv=("$@")
for (( j=0; j<argc; j++ )); do
echo "${argv[j]}"
done
인수 변수 수인 $#에 대한 루프도 작동합니다.
#! /bin/bash
for ((i=1; i<=$#; i++))
do
printf "${!i}\n"
done
./test.sh 1 2 '3 4'
출력:
1
2
3 4
baz의 답변을 증폭하면 특정 단어 검색과 같은 인덱스로 인수 목록을 열거해야 할 경우 목록을 복사하거나 변환하지 않고 이를 수행할 수 있습니다.
인수 목록을 이중 대시("--")로 분할하여 하나의 명령어로 대시 앞의 인수를 전달하고 대시 뒤의 인수를 다른 명령어로 전달합니다.
toolwrapper() {
for i in $(seq 1 $#); do
[[ "${!i}" == "--" ]] && break
done || return $? # returns error status if we don't "break"
echo "dashes at $i"
echo "Before dashes: ${@:1:i-1}"
echo "After dashes: ${@:i+1:$#}"
}
결과는 다음과 같습니다.
$ toolwrapper args for first tool -- and these are for the second
dashes at 5
Before dashes: args for first tool
After dashes: and these are for the second
aparse() {
while [[ $# > 0 ]] ; do
case "$1" in
--arg1)
varg1=${2}
shift
;;
--arg2)
varg2=true
;;
esac
shift
done
}
aparse "$@"
getopt 스크립트에서 명령어를 사용하여 명령줄 옵션 또는 파라미터의 형식을 지정합니다.
#!/bin/bash
# Extract command line options & values with getopt
#
set -- $(getopt -q ab:cd "$@")
#
echo
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) param="$2"
echo "Found the -b option, with parameter value $param"
shift ;;
-c) echo "Found the -c option" ;;
--) shift
break ;;
*) echo "$1 is not an option";;
esac
shift
언급URL : https://stackoverflow.com/questions/255898/how-to-iterate-over-arguments-in-a-bash-script
'sourcetip' 카테고리의 다른 글
UIView 및 iPhone UILabel의 그라데이션 (0) | 2023.04.18 |
---|---|
Excel VBA 코드: x64 버전에서의 컴파일 오류(PtrSafe 속성 필요) (0) | 2023.04.18 |
폴더에 포함된 모든 리소스 나열 (0) | 2023.04.18 |
Refresh WPF 명령어 (0) | 2023.04.18 |
[ Refresh ]또는 [Refresh All]버튼을 누른 후 매크로를 호출하는 방법 (0) | 2023.04.18 |