명령줄 인수가 없고 STDIN이 비어 있는지 확인하세요.

명령줄 인수가 없고 STDIN이 비어 있는지 확인하세요.

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 ...

관련 정보