Bash 스크립트에 명령줄 인수나 STDIN이 제공되지 않았는지 확인하는 방법은 무엇입니까?
내 말은 다음과 같이 실행하는 경우입니다.
#> ./myscript.sh
... Show message "No data provided..." and exit
또는:
#> ./myscript.sh filename.txt
... Read from filename.txt
또는:
#> ./myscript.sh < filename.txt**
... Read from STDIN
답변1
이것이 귀하의 요구 사항을 충족합니까?
#!/bin/sh
if test -n "$1"; then
echo "Read from $1";
elif test ! -t 0; then
echo "Read from stdin"
else
echo "No data provided..."
fi
주요 팁은 다음과 같습니다.
매개변수가 있는지 여부는
test -n $1
첫 번째 매개변수가 존재하는지 확인하여 수행됩니다.그런 다음
stdin
터미널에서 열려 있지 않은지 확인합니다(파일로 파이프되므로).test ! -t 0
파일 설명자 0(일명stdin
)이 열려 있지 않은지 확인하세요.마지막으로 다른 모든 것은 마지막 범주(
No data provided...
)에 속합니다.
답변2
여기저기 찾아보았지만 많은 시행착오 끝에 결국 정리할 수 있었습니다. 그 이후로 수많은 사용 사례에서 완벽하게 작동했습니다.
#!/bin/bash
### LayinPipe.sh
## Recreate "${@}" as "${Args[@]}"; appending piped input.
## Offers usable positional parameters regardless of where the input came from.
##
## You could choose to create the array with "${@}" instead following
## any piped arguments by simply swapping the order
## of the following two 'if' statements.
# First, check for normal positional parameters.
if [[ ${@} ]]; then
while read line; do
Args[${#Args[@]}]="${line}"
done < <(printf '%s\n' "${@}")
fi
# Then, check for piped input.
if [[ ! -t 0 ]]; then
while read line; do
Args[${#Args[@]}]="${line}"
done < <(cat -)
fi
# Behold the glory.
for ((a=0;a<${#Args[@]};a++)); do
echo "${a}: ${Args[a]}"
done
- 예: (이 솔루션의 유연성을 보여주기 위해 "ls" 출력을 입력으로 사용하는 것이 권장되지 않는다는 점을 충분히 이해하고 있습니다.)
$ ls
: TestFile.txt 'Filename with spaces'
$ ls -1 | LayinPipe.sh "$(ls -1)"
> 0: Filename with spaces
> 1: TestFile.txt
> 2: Filename with spaces
> 3: TestFile.txt
$ LayinPipe.sh "$(ls -1)"
> 0: Filename with spaces
> 1: TestFile.txt
$ ls -1 | LayinPipe.sh
> 0: Filename with spaces
> 1: TestFile.txt
답변3
[해결됨] bash 쉘에서...
... read -t 0: "도움말 읽기"를 참조하세요.
$ function read_if_stdin_not_empty {
if read -t 0 ; then
while read ; do
echo "stdin receive : $REPLY"
read_if_stdin_not_empty
done
else
echo "stdin is empty .."
fi
}
# TESTs:
$ read_if_stdin_not_empty
stdin is empty ..
$ echo '123' | read_if_stdin_not_empty
stdin receive : 123
$s='123
456'
$ echo "$s" | read_if_stdin_not_empty
stdin receive : 123
stdin receive : 456
답변4
나는 매우 흥미로운 이전 답변을 결합한 함수를 생각해 냈습니다.
파일 test.sh:
#!/bin/bash
function init_STDIN() {
## Version 1.0.0
## Creates the global variable array indexed STDIN
## which contains the possible lines sent in the
## file descriptor /dev/stdin of the script
declare -ga STDIN
read -t0 || return 1
while read LINE; do
STDIN[${#STDIN[@]}]="$LINE"
done < <(cat -)
test ${#STDIN[@]} -ne 0
}
if init_STDIN; then
echo "Feed provided on /dev/stdin. Processing..."
echo "For this example, /dev/stdin is:"
for ((I=0; I<${#STDIN[@]}; I++)); do
echo ${STDIN[$I]}
done
else
echo "Working without any feed on /dev/stdin..."
fi
echo
echo "For this example, the ${#@} parameter(s) provided on the command line is(are) :"
echo $@
시험:
$ ./test.sh some args ...
Working without any feed on /dev/stdin...
For this example, the 3 parameter(s) provided on the command line is(are) :
some args ...
$ seq 1 10 | sed 's/ /\n/g' | ./test.sh some args ...
Feed provided on /dev/stdin. Processing...
For this example, /dev/stdin is:
1
2
3
4
5
6
7
8
9
10
For this example, the 3 parameter(s) provided on the command line is(are) :
some args ...
$ seq 1 10 | sed 's/ /\n/g' | (exec 0<&-; ./test.sh some args ...)
Working without any feed on /dev/stdin...
For this example, the 3 parameter(s) provided on the command line is(are) :
some args ...