コマンドライン引数がなく、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 ...

関連情報