백그라운드에서 명령을 실행하는 스크립트가 있는데 정확히 그 일을 합니다. 문제는 스크립트가 읽기 명령을 만나면 일시 중지하고 입력을 받아들이지 않는다는 것입니다. 여기있어:
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
답변1
이 스크립트에는 많은 문제가 있지만 특정 문제를 일으키는 원인은 ls
파이프(의 출력)에서 데이터를 읽기 때문입니다.
1.파싱되지 않음ls
대신 이것을 사용하십시오
for currentSong in *; do
...
done
구문 분석을 하지 말아야 하는 많은 이유 중에서 ls
여러분이 보고 있는 문제는 STDIN이 출력에 연결되어 있기 때문입니다 ls
. 따라서 를 실행하면 read
STDIN이 터미널에 연결되어 있지 않기 때문에 터미널에서 읽을 수 없습니다.
2.더 많은 인용문 사용
꽤 많은 인용문이 있지만 여전히 몇 가지가 누락되어 있습니다. 주로 cd
.
cd "$musicPath"
반품
case "$choice"
삼.백틱을 사용하지 마세요
때로는 백틱을 사용해도 괜찮습니다. . 보다 낫기 때문에 명령줄에서 자주 사용합니다 $()
. 하지만 스크립팅에는 사용하는 $()
것이 더 좋습니다.
seconds="$(mdls "$currentSong"|sed -n '20p'|awk '{print $3}'|cut -d. -f1)"
4. 목차
mkdir
디렉토리가 이미 존재하는 경우 (해롭지는 않지만 시끄러운) 오류가 생성됩니다. -p
거기에 하나를 추가하십시오 mkdir
. 이미 존재하는 경우 자동으로 아무 작업도 수행되지 않습니다.
mkdir -p ../Yes
예, bash에는 많은 문제가 있습니다. 가혹하게 굴려고 노력하는 것이 아니라 단지 나쁜 습관을 고치려고 노력하는 것뿐입니다.
재미있게 보내세요 :-)