Lo script Bash non legge l'input


8

Ho uno script che suppone di eseguire un comando in background, e lo fa. Il problema è che quando lo script arriva su un comando di lettura, non si ferma e accetta l'input. Ecco qui:

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

in bash, puoi fornire il prompt nel comando read stesso:read -p "where is yo music? " musicPath
glenn jackman,

Risposte:


16

Ci sono numerosi problemi con quello script, ma quello che sta causando il tuo problema specifico è perché stai leggendo da una pipe (l'output di ls).

1. Non analizzarels

Usa questo invece

for currentSong in *; do
  ...
done

A parte i numerosi motivi che non dovresti analizzare ls, il problema che stai vedendo è perché STDIN è collegato all'output di ls. Quindi, quando si emette un read, non può leggere dal terminale perché STDIN non è collegato al terminale.


2. Usa più citazioni

Hai un buon numero di citazioni sparse in giro, ma mancano ancora alcune. Principalmente solo sul cd.

cd "$musicPath"

anche

case "$choice"


3. Non usare i backtick

L'uso dei backtick è ok a volte. Li uso spesso sulla riga di comando poiché è più veloce da digitare di $(). Ma per lo scripting è $()preferibile utilizzare invece.

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


4. mkdir

Il tuo mkdirgenererà un errore (innocuo ma rumoroso) se esistono già le directory. Aggiungi un -plà dentro che farà sì che il mkdirsilenzioso non faccia nulla se esiste già

mkdir -p ../Yes


Sì, ci sono molte insidie ​​con bash. Non cercare di essere duro, solo cercare di rompere le cattive abitudini.
Divertiti :-)


Grazie per tutti i suggerimenti! Adoro questa roba, quindi non preoccuparti. Mi piace sempre imparare cose nuove (:
Cade,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.