Bash脚本不读取输入


8

我有一个脚本,该脚本应该在后台运行命令,并且可以执行该命令。问题在于,当脚本执行读取命令时,它不会暂停并接受输入。这里是:

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

在bash中,您可以在read命令本身中提供提示:read -p "where is yo music? " musicPath
glenn jackman 2012年

Answers:


16

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

1. 不解析ls

用这个代替

for currentSong in *; do
  ...
done

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


2. 使用更多引号

您到处散布了大量的报价,但仍然缺少一些。主要只是在cd

cd "$musicPath"

case "$choice"


3. 不要使用反引号

有时可以使用反引号。我经常在命令行上使用它们,因为键入速度比快$()。但是,对于脚本编写,最好$()改用。

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


4. mkdir

mkdir如果目录已经存在,您将生成一个(无害但嘈杂的)错误。-p在其中添加一个将导致mkdir静默地不执行任何操作(如果已存在)

mkdir -p ../Yes


是的,bash有很多陷阱。不要试图苛刻,而只是要打破坏习惯。
玩得开心 :-)


感谢所有提示!我喜欢这个东西,所以不用担心。永远喜欢学习新事物(:
Cade 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.