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