stdinがシェル関数にパイプされるかどうかを検出する

stdinがシェル関数にパイプされるかどうかを検出する

私はコマンドライン環境とシェルスクリプトで多くのシェル機能を使います。データがパイプで接続されているかどうかによって、2つの合計が異なる動作をしたいupperと思います。lower現在作成されている両方の関数は、渡された引数を介して入力を受け取ります。

これは次の定義ですupper

upper () {
    my_echo "${1}" | tr "[:lower:]" "[:upper:]"
    return 0
}

これは次の定義ですlower

lower () {
    my_echo "${1}" | tr "[:upper:]" "[:lower:]"
    return 0
}

my_echoは置換するために作成したPythonスクリプトですecho。エスケープシーケンスをリテラルに変換するときに引数として渡されたすべての内容を出力する必要があります。文字列をオプションとして解釈せずに印刷できます。Unixコンソールの動作方法は邪魔ですとなります-eecho

これらの機能には以前のバージョンがいくつかあります。標準入力で実行されるバージョンの定義は次のとおりです。

upper () {
    tr "[:lower:]" "[:upper:]"
}

lower () {
    tr "[:upper:]" "[:lower:]"
}

関数がパイプで接続されている場合は、上記のように機能する必要があります。そうでない場合は、最初の引数を読む必要があります。

答え1

あなたのコード:

upper () {
    my_echo "${1}" | tr "[:lower:]" "[:upper:]"
    return 0
}

引数がない場合は標準入力から読み込みます。

upper () {
    ( (( $# )) && printf '%s\n' "$@" || cat ) |
    tr '[:lower:]' '[:upper:]'
}

これは$#位置引数の数をテストし、その数値がゼロの場合はcat標準入力ストリームから読み取られたデータを使用し、そうでない場合はprintf位置引数を使用します。それからtr

return 0パイプの実際の終了状態を知りたいかもしれないので削除しました。

では、bash次のことができます。

upper () {
    (( $# )) && printf '%s\n' "${@^^}" || tr '[:lower:]' '[:upper:]'
}

これは引数がある場合はまったく使用されませんが、tr代わりにBashの${parameter^^pattern}置換を使用してすべての引数を大文字に変換します(,,小文字を使用)。

printfフォーマット文字列を変更したり変更したりしない可能性があるため、達成したい目標'%s 'によって異なります。'%s\n'

関連情報