Skrip Bash tidak membaca input

8

Saya memiliki skrip yang seharusnya menjalankan perintah di latar belakang, dan ia melakukannya. Masalahnya adalah bahwa ketika skrip datang pada perintah baca, itu tidak berhenti dan menerima input. Ini dia:

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
Tong kecil
sumber
di bash, Anda dapat memberikan prompt dalam perintah baca itu sendiri:read -p "where is yo music? " musicPath
glenn jackman

Jawaban:

16

Ada banyak masalah dengan skrip itu, tetapi yang menyebabkan masalah spesifik Anda adalah karena Anda membaca dari sebuah pipa (hasil dari ls).

1. Jangan parsels

Gunakan ini sebagai gantinya

for currentSong in *; do
  ...
done

Selain dari banyak alasan Anda tidak perlu menguraikan ls, masalah yang Anda lihat adalah karena STDIN terhubung ke output ls. Jadi ketika Anda mengeluarkan a read, itu tidak dapat membaca dari terminal karena STDIN tidak terhubung ke terminal.


2. Gunakan lebih banyak kutipan

Anda memiliki cukup banyak kutipan yang tersebar, tetapi masih ada beberapa kutipan yang hilang. Terutama hanya di cd.

cd "$musicPath"

juga

case "$choice"


3. Jangan gunakan backticks

Kadang-kadang menggunakan backticks ok. Saya sering menggunakannya di baris perintah karena lebih cepat untuk mengetik daripada $(). Tetapi untuk skrip, lebih baik menggunakan praktik $()saja.

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


4. mkdir

Anda mkdirakan menghasilkan kesalahan (tidak berbahaya tapi berisik) jika direktori sudah ada. Tambahkan -pdi sana yang akan menyebabkan mkdirdiam-diam tidak melakukan apa pun jika sudah ada

mkdir -p ../Yes


Ya, ada banyak jebakan dengan bash. Bukan berusaha bersikap kasar, hanya berusaha menghentikan kebiasaan buruk.
Selamat bersenang-senang :-)

Patrick
sumber
Terima kasih untuk semua tipsnya! Saya suka barang ini, jadi jangan khawatir. Selalu suka belajar hal-hal baru (:
Cade