Bash 脚本不读取输入

Cad*_*ade 8 shell bash input shell-script

我有一个假设在后台运行命令的脚本,它就是这样做的。问题是当脚本遇到读取命令时,它不会暂停并接受输入。这里是:

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
Run Code Online (Sandbox Code Playgroud)

phe*_*mer 16

该脚本有很多问题,但导致您出现特定问题的问题是因为您正在从管道( 的输出ls)中读取数据。

1.不要解析ls

改用这个

for currentSong in *; do
  ...
done
Run Code Online (Sandbox Code Playgroud)

除了您不应该解析的众多原因之外ls,您看到的问题是因为 STDIN 连接到ls. 因此,当您发出 a 时read,它无法从终端读取,因为 STDIN 未连接到终端。


2.使用更多引号

您已经获得了大量的报价,但仍然缺少一些。主要只是在cd.

cd "$musicPath"
Run Code Online (Sandbox Code Playgroud)

case "$choice"
Run Code Online (Sandbox Code Playgroud)


3.不要使用反引号

有时使用反引号是可以的。我经常在命令行上使用它们,因为它比$(). 但是对于脚本,最好使用它来$()代替。

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


4.mkdir

mkdir如果目录已经存在,您将生成一个(无害但嘈杂的)错误。-p在那里添加一个,mkdir如果它已经存在,它将导致静默不做任何事情

mkdir -p ../Yes
Run Code Online (Sandbox Code Playgroud)


是的,bash 有很多陷阱。不是想变得苛刻,只是想改掉坏习惯。
玩得开心 :-)