instance라는 파일에 스크립트가 있습니다.
echo "hello world"
echo ${1}
그리고 내가 다음을 사용 하여이 스크립트를 실행할 때 :
./instance solfish
나는이 출력을 얻는다 :
hello world
solfish
그러나 내가 달릴 때 :
echo $#
“0”이라고 표시되어 있습니다. 왜? 무슨 $#
뜻 인지 모르겠습니다 .
설명해주세요.
답변
$#
는 bash
인수의 수 (위치 매개 변수)로 확장 되는 특수 변수입니다 . 즉, 인수 $1, $2 ...
가 쉘에 직접 전달 된 경우 (예 : in) 해당 스크립트 또는 쉘에 전달됩니다 bash -c '...' ....
.
이것은 argc
C 와 비슷합니다 .
아마도 이것은 분명해질 것입니다 :
$ bash -c 'echo $#'
0
$ bash -c 'echo $#' _ x
1
$ bash -c 'echo $#' _ x y
2
$ bash -c 'echo $#' _ x y z
3
참고 것으로는 bash -c
0부터 시작하여 다음 명령 후 인수를 취하는 ( $0
, 기술적으로, 그것은 단지 bash
당신이 설정시키기의의 방법으로 $0
정말로 인수,) 그래서 _
그냥 자리로 여기에 사용된다; 실제 인수는 x
( $1
), y
( $2
) 및 z
( $3
)입니다.
마찬가지로 다음과 같은 script.sh
경우 스크립트 (가정 )에서
#!/usr/bin/env bash
echo "$#"
그런 다음에 할 때 :
./script.sh foo bar
스크립트는 2를 출력합니다; 마찬가지로,
./script.sh foo
1을 출력합니다.
답변
echo $#
스크립트의 위치 매개 변수 수를 출력합니다.
아무것도 없으므로 0을 출력합니다.
echo $#
별도의 명령이 아니라 스크립트 내에서 유용합니다.
다음과 같은 일부 매개 변수를 사용하여 스크립트를 실행하면
./instance par1 par2
echo $#
스크립트가 출력 2에 위치.
답변
$#
일반적으로 매개 변수가 전달되도록 bash 스크립트에서 사용됩니다. 일반적으로 스크립트 시작 부분에서 매개 변수를 확인합니다.
예를 들어 다음은 오늘 작업 한 스크립트의 스 니펫입니다.
if [[ $# -ne 1 ]]; then
echo 'One argument required for file name, e.g. "Backup-2017-07-25"'
echo '.tar will automatically be added as a file extension'
exit 1
fi
요약 $#
하면 스크립트에 전달 된 매개 변수의 수를보고합니다. 귀하의 경우 매개 변수를 전달하지 않았으며보고 된 결과는 0
입니다.
#
배쉬의 다른 용도
가 #
종종 발생 횟수 또는 가변 길이를 계산하는 떠들썩한 파티에서 사용된다.
문자열의 길이를 찾으려면
myvar="some string"; echo ${#myvar}
보고: 11
배열 요소 수를 찾으려면
myArr=(A B C); echo ${#myArr[@]}
보고: 3
첫 번째 배열 요소의 길이를 찾으려면
myArr=(A B C); echo ${#myArr[0]}
반환 값 : 1
( A
배열은 0부터 시작하는 인덱스 / 첨자를 사용하므로, 길이는 0입니다.)
답변
$#
인수의 수이지만 함수에서 다를 수 있음을 기억하십시오.
$#
스크립트, 쉘 또는 쉘 함수에 전달 된 위치 매개 변수의 수입니다 . 쉘 함수가 실행되는 동안 위치 매개 변수가 함수의 인수로 임시 대체 되기 때문 입니다. 이를 통해 함수는 자체 위치 매개 변수를 승인하고 사용할 수 있습니다.
이 스크립트 는 함수 3
자체 "$#"
가 함수에 f
전달 된 인수 수로 확장 되기 때문에 스크립트 자체에 전달 된 인수 수에 관계없이 항상를 인쇄 합니다.
#!/bin/sh
f() {
echo "$#"
}
f a b c
쉘 함수에서 위치 매개 변수의 작동 방식에 익숙하지 않은 경우 다음과 같은 코드가 예상대로 작동하지 않기 때문에 중요합니다.
#!/bin/sh
check_args() { # doesn't work!
if [ "$#" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$0" "$#" >&2
exit 1
fi
}
# Maybe check some other things...
check_args
# Do other stuff...
에서 check_args
, $#
해당 스크립트에 항상 0입니다 기능 자체에 전달 된 인수의 수를 확장합니다.
쉘 기능에서 이러한 기능을 원한다면 다음과 같이 작성해야합니다.
#!/bin/sh
check_args() { # works -- the caller must pass the number of arguments received
if [ "$1" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$0" "$1" >&2
exit 1
fi
}
# Maybe check some other things...
check_args "$#"
이것은 함수 외부$#
로 확장 되어 위치 매개 변수 중 하나로 함수에 전달 되기 때문에 작동합니다 . 함수 내 에서 일부 스크립트에 포함되지 않고 쉘 함수에 전달 된 첫 번째 위치 매개 변수로 확장됩니다.$1
따라서, 같은 $#
특수 매개 변수 $1
, $2
등뿐만 아니라, $@
하고 $*
, 또한이 기능으로 확장되는 함수에 전달 된 인수와 관련. 그러나 함수 이름으로 변경 $0
되지 않으므로 품질 오류 메시지를 생성하는 데 계속 사용할 수 있습니다.
$ ./check-args-demo a b c
./check-args-demo: error: need 2 arguments, got 3
마찬가지로, 하나의 함수를 다른 함수 안에 정의하면 확장이 수행되는 가장 안쪽 함수에 전달 된 위치 매개 변수를 사용하는 것입니다.
#!/bin/sh
outer() {
inner() {
printf 'inner() got %d arguments\n' "$#"
}
printf 'outer() got %d arguments\n' "$#"
inner x y z
}
printf 'script got %d arguments\n' "$#"
outer p q
이 스크립트를 호출 nested
하고 (실행 후 chmod +x nested
) 실행했습니다.
$ ./nested a
script got 1 arguments
outer() got 2 arguments
inner() got 3 arguments
예, 알아요 “1 개의 인자”는 복수형 버그입니다.
위치 매개 변수도 변경할 수 있습니다.
스크립트를 작성하는 경우 함수 외부의 위치 매개 변수 는 변경하지 않는 한 스크립트에 전달되는 명령 행 인수 입니다.
이를 변경하는 하나의 일반적인 방법은 함께 shift
제를 적하하고 감소 의해 왼쪽으로 각 위치 파라미터를 이동 내장, $#
1 :
#!/bin/sh
while [ "$#" -ne 0 ]; do
printf '%d argument(s) remaining.\nGot "%s".\n\n' "$#" "$1"
shift
done
$ ./do-shift foo bar baz # I named the script do-shift.
3 argument(s) remaining.
Got "foo".
2 argument(s) remaining.
Got "bar".
1 argument(s) remaining.
Got "baz".
set
내장 기능 으로 변경할 수도 있습니다 .
#!/bin/sh
printf '%d args: %s\n' "$#" "$*"
set foo bar baz
printf '%d args: %s\n' "$#" "$*"
$ ./set-args a b c d e # I named the script set-args.
5 args: a b c d e
3 args: foo bar baz