O script Bash não lê a entrada

8

Eu tenho um script que é suposto executar um comando em segundo plano, e faz isso. O problema é que, quando o script se depara com um comando de leitura, ele não pausa e aceita entrada. Aqui 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
fonte
em bash, você pode fornecer o prompt no próprio comando de leitura:read -p "where is yo music? " musicPath
Glenn Jackman

Respostas:

16

Existem vários problemas com esse script, mas o que está causando o seu problema específico é porque você está lendo em um canal (a saída de ls).

1. Não analisels

Use isso em vez disso

for currentSong in *; do
  ...
done

Além das inúmeras razões pelas quais você não deve analisar ls, o problema que você está vendo é que o STDIN está conectado à saída de ls. Portanto, quando você emite um read, ele não pode ser lido no terminal porque o STDIN não está conectado ao terminal.


2. Use mais citações

Você tem uma boa quantidade de citações espalhadas, mas ainda falta algumas. Principalmente apenas no cd.

cd "$musicPath"

Além disso

case "$choice"


3. Não use backticks

Usar backticks está ok às vezes. Costumo usá-los na linha de comando, pois é mais rápido digitar do que $(). Mas para scripts, é uma boa prática usar $().

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


4. mkdir

Você mkdirirá gerar um erro (inofensivo, mas barulhento) se os diretórios já existirem. Adicione um -plá que fará com que o mkdirsilenciosamente não faça nada se ele já existir

mkdir -p ../Yes


Sim, existem muitas armadilhas com o bash. Não tentando ser duro, apenas tentando quebrar maus hábitos.
Diverta-se :-)

Patrick
fonte
Obrigado por todas as dicas! Eu amo essas coisas, então não se preocupe. Sempre adoro aprender coisas novas (:
Cade