Tập lệnh Bash không đọc đầu vào


8

Tôi có một kịch bản giả sử chạy một lệnh trong nền và nó thực hiện điều đó. Vấn đề là khi tập lệnh xuất hiện lệnh đọc, nó không tạm dừng và chấp nhận đầu vào. Đây là:

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

trong bash, bạn có thể cung cấp lời nhắc trong chính lệnh đọc:read -p "where is yo music? " musicPath
glenn jackman

Câu trả lời:


16

Có rất nhiều vấn đề với tập lệnh đó, nhưng vấn đề gây ra vấn đề cụ thể của bạn là do bạn đang đọc từ một đường ống (đầu ra của ls).

1. Đừng phân tíchls

Sử dụng cái này thay thế

for currentSong in *; do
  ...
done

Ngoài nhiều lý do bạn không nên phân tích cú pháp ls, vấn đề bạn gặp phải là do STDIN được kết nối với đầu ra của ls. Vì vậy, khi bạn phát hành một read, nó không thể đọc từ thiết bị đầu cuối vì STDIN không được kết nối với thiết bị đầu cuối.


2. Sử dụng nhiều trích dẫn

Bạn đã có một số lượng lớn các trích dẫn được lan truyền xung quanh, nhưng vẫn còn thiếu một số. Chủ yếu chỉ trên cd.

cd "$musicPath"

cũng thế

case "$choice"


3. Không sử dụng backticks

Sử dụng backticks đôi khi là ok. Tôi thường xuyên sử dụng chúng trên dòng lệnh vì nó gõ nhanh hơn $(). Nhưng để viết kịch bản, thay vào đó là cách thực hành tốt $().

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


4. mkdir

Bạn mkdirsẽ tạo ra một lỗi (vô hại nhưng ồn ào) nếu các thư mục đã tồn tại. Thêm một -ptrong đó sẽ khiến mkdircho âm thầm không làm gì nếu nó đã tồn tại

mkdir -p ../Yes


Vâng, có rất nhiều cạm bẫy với bash. Không cố tỏ ra gay gắt, chỉ cố phá bỏ những thói quen xấu.
Chúc vui vẻ :-)


Cảm ơn tất cả các lời khuyên! Tôi yêu những thứ này, vì vậy không phải lo lắng. Luôn thích học hỏi những điều mới (:
Cade
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.