sedを介してstderrをフィルタリングすると、Bashスクリプトはクラッシュします。

sedを介してstderrをフィルタリングすると、Bashスクリプトはクラッシュします。

紹介する

bashで動作するスクリプトがありsshparallel並列バージョンではGNUを使用し、順次バージョンではforループを使用します。

スクリプトは次のように使用されます。

foreach_server "cd $dir && find -name '*.png' | wc -l"
foreach_server "cd $dir && git --no-pager status"

conda時には環境で実行可能ファイルにアクセスする必要があります(https://docs.conda.io/en/latest/)、これを行うために私が見つけた唯一の方法は、対話型シェルを使用することです。つまり、bash -ic実行したいコマンドの直前にthisを使用してssh $host bash -ic $cmdconda環境がロードされるようにします。残念ながら、これはstderr回避できない2つのエラーメッセージを生成します。

bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell

sedだから、これら2つの行を削除し、stderr次に別の行を渡すフィルタを作成しましたstderr

ssh $host "$@" 2> >(sed -e "$filter1" -e "$filter2" >&2)

問題:sedフィルタは並列バージョンを中断します。

フィルタはsed順次バージョンではうまく機能しますが、並列バージョンはスクリプトの最後で中断され、sedプロセスはアクティブですが、何もしません。これが起こらないようにするにはどうすればよいですか?

問題がプロセスの代替であると疑われますが、実際に問題を診断することはできません。

参照スクリプト

#!/bin/bash
set -u

exit_trap() {
    echo "Interrupted"
    exit 1
}

trap exit_trap SIGINT

filter1='/^bash: cannot set terminal process group/d'
filter2='/^bash: no job control in this shell/d' 

hosts=("host1" "host2")  # more hosts in the real file

if [ -z ${serial+x} ];
then
    # Parallel version ==> THIS VERSION HANGS AT THE END, AFTER ALL OUTPUT HAS BEEN WRITTEN
    echo ${hosts[@]} | sed 's/ /\n/g' | parallel "echo ----- {} ----- && ssh {} \"$@\"" 2> >(sed -e "$filter1" -e "$filter2" >&2)
else
    # Serial version ==> THIS VERSION WORKS FINE
    for host in ${hosts[@]};
    do
        echo "------------------ $host ------------------"

        ssh $host "$@" 2> >(sed -e "$filter1" -e "$filter2" >&2)

        echo "--------------------------------------$(echo $host | sed 's/./-/g')"
    done
fi

答え1

エラーメッセージの症状を取り除こうとするよりも、エラーメッセージの原因を取り除く方が良いでしょう。

sshこれにより、端末ioctlを適用できるようにセッションにttyが割り当てられます。

ssh -t $host "$@"

実際に行を呼び出す方法によっては、フラグを2倍にする必要があります-t-tt

しかし、根本的な問題は、conda環境を設定するためにインタラクティブシェルが必要であるようです。その理由は にあるからがほぼ確実です~/.bashrc.これを明示的に実行するか、関連コマンドを抽出してスクリプトで使用できます。

私もよくわかりませんが、conda質問です。.bashrcでconda環境を有効にする方法は?~/.bashrc必要な関連部分はAskUbuntuで参照されているようです。

関連情報