1. ホーム
  2. linux

[解決済み] bash関数へのパイプ出力

2023-04-30 13:09:20

質問

bashスクリプトに簡単な関数があり、入力としてstdoutをパイプしたいのですが、どうすればいいですか?

jc_hms(){
  printf "$1"
}

このように使いたい。

var=`echo "teststring" | jc_hms`

もちろん、質問を単純化するために冗長な関数echoとprintfを使用しましたが、あなたはアイデアを得ることができます。 今現在、私は "not found" エラーを受け取りますが、これは私のパラメータの区切りが間違っている("$1"の部分)ことを意味していると思います。 何か提案はありますか?

元々jc_hms関数はこのように使用されていました。

echo `jc_hms "teststring"` > //dev/tts/0

というようなことを書いていますが、シリアルポートに送る前に、まず結果を変数に保存して、さらに処理したいと思います。

編集 私は、bash 関数に "|" パイプ文字でインターフェイスしたいのですが、これが可能かどうか疑問に思っているのです。

EDIT: さて、ここに完全な関数があります。

jc_hms(){
  hr=$(($1 / 3600))
  min=$(($1 / 60))
  sec=$(($1 % 60))

  printf "$hs:%02d:%02d" $min $sec
}

私は、このコードの行に来る文字列を形成するために関数を使用しています。

songplaytime=`echo $songtime | awk '{print S1 }'`
printstring="`jc_hms $songplaytime`"  #store resulting string in printstring

ここで、$songtimeはスペースで区切られた"playtime totaltime"として表現される文字列です。

これを1行でやって、awkの後にパイプでつなげばいいのですが

printstring=`echo $songtime | awk '{print S1 }' | jc_hms`

というように

どのように解決するのですか?

実際の質問に答えると、シェル関数がパイプの受信側にいるとき、標準入力は、以下のように継承されます。 すべて コマンドに継承されますが、実際に標準入力を読み込むコマンドだけがデータを消費します。次々と実行されるコマンドの場合、後のコマンドは前のコマンドによって消費されなかったものだけを見ることができます。2 つのコマンドが並行して実行される場合、どのコマンドがどのデータを見るかは、OS がコマンドをどのようにスケジュールするかに依存します。

では printf が関数内の最初で唯一のコマンドであるため、標準入力は事実上無視されます。これを回避する方法はいくつかあり、例えば read に渡すことができる変数に標準入力を読み込むために、 を使用することです。 printf :

jc_hms () {
    read foo
    hr=$(($foo / 3600))
    min=$(($foo / 60))
    sec=$(($foo % 60))
    printf "%d:%02d:%02d" "$hr" "$min" "$sec"
}

しかし、パイプラインの必要性は、あなたの認識する awk を使用する必要性に依存しているようなので、次の代替案を提案させてください。

printstring=$( jc_hms $songtime )

以降 songtime はスペースで区切られた数字の組で構成されているので、 シェルは songtime の値に対して単語分割を行い jc_hms は2つの別々のパラメータを見ることになります。これには jc_hms の定義に変更はなく、標準入力から何かをパイプする必要もありません。

もし、まだ別の理由で jc_hms が標準入力を読み取るための別の理由がまだある場合は、私たちに教えてください。