Bashスクリプトが入力を読み取らない

Bashスクリプトが入力を読み取らない

バックグラウンドでコマンドを実行するスクリプトがありますが、まさにそれを行います。問題は、スクリプトが読み取りコマンドに出会うと一時停止して入力を受け付けないことです。ここにいる:

printf "Where is yo music?: "
read musicPath

cd $musicPath
ls | while read currentSong;do
  seconds=`mdls "$currentSong"|sed -n '20p'|awk '{print $3}'|cut -d. -f1`
  hours=$((seconds / 3600))
  seconds=$((seconds % 3600))
  minutes=$((seconds / 60))
  seconds=$((seconds % 60))
  echo "Song: $currentSong"
  echo "Length: $hours:$minutes:$seconds"
  afplay "$currentSong"&
  printf "yes (y), no (n), or maybe (m): "
  read choice
  case $choice in
    y)
      mkdir ../Yes
      mv "$currentSong" ../Yes
    ;;
    n)
      mkdir ../No
      mv "$currentSong" ../No
    ;;
    m)
      mkdir ../Maybe
      mv "$currentSong" ../
    ;;
    *)
      echo "Invalid option! Continuing..."
    ;;
  esac
  kill $!
done

答え1

このスクリプトには多くの問題がありますが、特定の問題を引き起こす原因は、lsパイプ(の出力)からデータを読み取るためです。

1.解析されないls

代わりにこれを使用してください

for currentSong in *; do
  ...
done

解析しないでください多くの理由のうち、lsあなたが見ている問題は、STDINが出力に接続されているためですls。そのため、実行するとreadSTDINが端末に接続されていないため、端末から読み取ることができません。


2.より多くの引用を使う

かなり多くの引用がありますが、まだいくつか欠けています。主にcd

cd "$musicPath"

返品

case "$choice"


三。バックティックを使用しないでください

時にはバックティックを使っても大丈夫です。 。より良いので、コマンドラインでよく使用します$()。しかし、スクリプトに使用する方$()が良いです。

seconds="$(mdls "$currentSong"|sed -n '20p'|awk '{print $3}'|cut -d. -f1)"


4. 目次

mkdirディレクトリがすでに存在する場合(有害ではありませんが騒々しい)、エラーが生成されます。-pそこに1つを追加してくださいmkdir。すでに存在する場合、自動的には何も実行されません。

mkdir -p ../Yes


はい、bashには多くの問題があります。厳しく転がろうとするのではなく、悪い習慣を直そうとするだけです。
楽しんでください:-)

関連情報