8

I have a script that is suppose to run a command in the background, and it does that. The problem is that when the script comes upon a read command, it doesn't pause and accept input. Here it is:

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
  • in bash, you can provide the prompt in the read command itself: read -p "where is yo music? " musicPath Aug 12, 2012 at 23:51

1 Answer 1

16

There are numerous issues with that script, but the one thats causing your specific issue is because you're reading from a pipe (the output of ls).

1. Don't parse ls

Use this instead

for currentSong in *; do
  ...
done

Aside from the numerous reasons you shouldnt parse ls, the issue you're seeing is because STDIN is connected to the output of ls. So when you issue a read, it can't read from the terminal because STDIN isn't connected to the terminal.


2. Use more quotes

You've got a fair amount of quotes spread around, but still missing some. Mainly just on the cd.

cd "$musicPath"

also

case "$choice"


3. Don't use backticks

Using backticks is ok sometimes. I frequently use them on the command line as it faster to type than $(). But for scripting, it's good practice to use $() instead.

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


4. mkdir

Your mkdir will generate an (harmless but noisy) error if the directories already exist. Add a -p in there which will cause the mkdir to silently do nothing if it already exists

mkdir -p ../Yes


Yes, there are a lot of pitfalls with bash. Not trying to be harsh, just trying to break bad habits.
Have fun :-)

1
  • Thanks for all of the tips! I love this stuff, so no worries. Always love learning new things (:
    – Cade
    Aug 12, 2012 at 4:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.