シェルスクリプトでwhile内のでsshコマンドを使用すると1回しか処理されない

2021-06-22

シェルスクリプトでwhile文を利用して、そのループ処理内にsshコマンドを使用するとループ処理されずに1回のみとなる場合の対処方法です

下記のシェルスクリプトでは、LIST_FILE=/home/admin/list.txt にファイル名があり、そのファイルがリモート先に無ければSCPでコピーするような処理です

但し、while文でのループ処理でファイル内の複数行あると最後の行まで実行されますが、ループ処理内でssh等のコマンドがあると1回しか処理されません

LIST_FILE=/home/admin/list.txt

while read line
do
  FILE_CHK=`ssh -l admin 192.168.0.50 "ls ${line} 2>/dev/null"`

  if [ -z ${FILECHK} ]; then
    scp ${line} 192.168.0.50:/home/admin/
  fi

done < ${LIST_FILE}

ループ内でsshの処理があるとファイル全体が渡さるようで、その際にファイル無いが空となり読み込む行がないので1回のみとなります。この処理を回避するには「ssh -n」とオプションをつけて、標準入力を/dev/null からリダイレクトすると良いようです

修正したスクリプトは以下となります

LIST_FILE=/home/admin/list.txt

while read line
do
  FILE_CHK=`ssh -n -l admin 192.168.0.50 "ls ${line} 2>/dev/null"`

  if [ -z ${FILECHK} ]; then
    scp ${line} 192.168.0.50:/home/admin/
  fi

done < ${LIST_FILE}