La secuencia de comandos Bash no lee la entrada

8

Tengo un script que se supone que ejecuta un comando en segundo plano, y lo hace. El problema es que cuando la secuencia de comandos se encuentra con un comando de lectura, no se detiene y no acepta entradas. Aquí está:

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
Cade
fuente
en bash, puede proporcionar el aviso en el comando de lectura en sí:read -p "where is yo music? " musicPath
glenn jackman

Respuestas:

16

Hay numerosos problemas con ese script, pero el que está causando su problema específico es porque está leyendo desde una tubería (la salida de ls).

1. No analizarls

Use esto en su lugar

for currentSong in *; do
  ...
done

Además de las numerosas razones por las que no debe analizar ls, el problema que está viendo es porque STDIN está conectado a la salida de ls. Entonces, cuando emite un read, no puede leer desde el terminal porque STDIN no está conectado al terminal.


2. Use más citas

Tienes una buena cantidad de cotizaciones repartidas, pero aún faltan algunas. Principalmente solo en el cd.

cd "$musicPath"

además

case "$choice"


3. No uses backticks

Usar backticks está bien a veces. Con frecuencia los uso en la línea de comandos, ya que es más rápido de escribir que $(). Pero para las secuencias de comandos, es una buena práctica usar $()en su lugar.

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


4. mkdir

Su mkdirgenerará un error (inofensivo pero ruidoso) si los directorios ya existen. Agregue un -pallí que hará mkdirque silenciosamente no haga nada si ya existe

mkdir -p ../Yes


Sí, hay muchas trampas con bash. No tratando de ser duro, solo tratando de romper los malos hábitos.
Que te diviertas :-)

Patricio
fuente
Gracias por todos los consejos! Me encantan estas cosas, así que no te preocupes. Siempre me encanta aprender cosas nuevas (:
Cade