163


標準入力が与えられた場合はそちらを行ごとに、そうでない場合は引数をまるまる1行として扱うスクリプトを作ろうとしています。

[code]

    #!/bin/sh
    
    fetch_input () {
        [ -t 0 ] && echo "$1" || cat -
    }
    
    fetch_input "$*" | while IFS= read -r line
    do
        echo "reading: $line"
    done
    
[/code]

標準入力が存在するかチェックするのに上のように`[ -t
0]`を使用すると大抵の場合はうまくいくのですが、インタラクティブシェルで動かすことが前提になるため、sshなどでリモートマシンのスクリプトを動かそうとすると`-t`オプションで仮想端末を用意する必要がでてしまいます。

[code]

    ssh -t remote '/path/to/script.sh foo bar'
    
[/code]

この場合、もっと単純に標準入力と引数のどちらにも対応できるスクリプトを書く方法はありますか？


CC BY-SA 3.0
2014-11-11T14:44:13.173
162
2019-11-23T15:05:11.067
2015-07-10T22:28:40.983
2349
62
question
sh
標準入力と引数のどちらにも対応したbourne-shellスクリプト


普通※は引数の有無で判定します。（※例：`cat`） `$#` で引数の数が分かるので↓とか

[code]

    { test $# = 0 && cat || echo "$*"; }
    
[/code]


CC BY-SA 3.0
2014-11-12T15:57:17.580
163
2014-11-12T15:57:17.580
81
162
answer


別解です。  
変数の展開機能を利用して、引数がない場合は標準入力(`cat`の実行結果の置換)、あれば引数を使用する。

[code]

    ${@:-"`cat`"}
    
[/code]

`bash`ならば次の例も使えます。

[code]

    ${@:-"$(cat)"}
    
[/code]

【使用例】

[code]

    printf "%s"  ${@:-"`cat`"}
    
[/code]


CC BY-SA 4.0
2019-11-23T15:05:11.067
60794
2019-11-23T15:05:11.067
35558
162
answer