사용자에게 특정 유형의 파일을 요청하도록 스크립트를 조정하고 있습니다. 입력한 파일이 특정 파일 형식과 일치하지 않으면 while 루프에 들어가 사용자가 올바른 파일을 입력할 때까지 반복됩니다.
이 경우 사용자에게 다음 .zip
파일을 요청합니다.
read -p "Enter zip file: " package1
while [ package1 != *.zip ] ; do
read -p "Please enter file ending in '.zip': " package1
done <<< package1
echo $package1
지금까지 오류가 있었습니다. 이제 빈 커서만 표시되고 출력은 표시되지 않습니다. 입력 여부에 관계없이 *.zip
공백 커서가 있고 출력이 없는 상태로 다음 줄로 진행됩니다.
생각?
편집하다:
좋아, 나는 루프를 사용하기로 결정했고 이 경우 select
보다 훨씬 더 나은 선택입니다 .while
하지만 해당 zip
파일(또는 프롬프트된 파일 유형)이 다른 디렉토리에 있을 수 있다면 어떻게 될까요? 쉘 에 있는 동안 디렉토리를 변경할 수 있는 옵션을 제공하고 싶습니다 select-loop
.
나는 지금까지 시도했다:
echo Select zip file:
options=(".." *.zip)
select package1 in "${options[@]}" ; do
case $package1 in
1 ) cd ..; echo Select zip file: ;;
# Different Directory ) ;;
* ) break ;;
esac
done
그러나 루프는 디렉토리를 변경한 후 메뉴 항목을 다시 표시하지 않습니다. 사용자가 원하는 cd
것과는 완전히 다른 경로를 제공하는 방법 ../
이나 용도가 무엇인지 잘 모르겠습니다.
"All other existing \# file items" ) ... ; break;;
내면에case
답변1
최종 확장만 검사하여 논리적으로 더 쉽게 만듭니다.
while [ "${package1##*.}" != "zip" ]
do
read -e -p "Specify a .zip file: " package1
done
echo $package1
답변2
보다 세련된 솔루션이 게시되었지만 원본 스크립트의 실패를 초래하는 일부 오류와 이를 해결하는 방법을 지적하는 것이 중요하다고 생각합니다.
먼저 while 루프에서 변수를 테스트할 때 해당 변수에 저장된 실제 데이터를 읽으려면 변수 앞에 package1
를 배치해야 합니다 .$
다음에는 while 루프 테스트 [[...]]
대신 [...]
에 사용하세요. 이렇게 하면 와일드카드를 사용하여 패턴 일치를 수행할 수 있습니다 *
. 그러나 이것은 sh가 아닌 bash에서만 작동합니다. 참조하세요이것[[...]]
vs 사용에 대한 자세한 설명은 답변을 참조하세요 [...]
.
<<< package1
마지막으로 while 루프 끝에 문자열을 전달할 필요가 없습니다 .
다음은 의도한 대로 작동하는 스크립트의 수정된 버전입니다.
#!/bin/bash
read -p "Enter zip file: " package1
while [[ "$package1" != *.zip ]]; do
read -p "Please enter file ending in '.zip': " package1
done
echo $package1
답변3
사용자가 대화형으로 파일 경로 이름을 입력하도록 유도하지 마십시오. 스크립트의 명령줄에서 Zip 아카이브 파일의 경로 이름을 사용하여 스크립트를 호출하는 것이 더 쉽습니다. 이를 통해 쉘의 파일 이름 완성 기능과 파일 이름 글로빙 패턴을 사용할 수 있습니다.
스크립트는 다음을 사용하여 호출됩니다.
./myscript /some/path/myarchive.zip
또는
./myscript folder/archive-*.zip
또는 유사합니다.
스크립트에서 당신은 할 것입니다
#!/bin/bash
for archive_path do
printf 'Processing archive "%s"...\n' "$archive_path"
# code to process "$archive_path" goes here
done
스크립트의 루프는 스크립트에 전달된 모든 인수에 대해 반복되며 각 반복에서 "$archive_path"
스크립트에 전달된 개별 아카이브의 경로 이름이 됩니다.
"$archive_path"
아카이브에서 사용할 도구는 파일 이름 접미사에 신경 쓰지 않을 수도 있으므로 파일 이름이 특정 문자열로 끝나는지 확인할 필요가 없습니다 . 그렇다면 쉽게 잡을 수 있는 적절한 종료 코드로 인해 실패하게 됩니다.
if ! unzip "$archive_path"; then
printf 'Failed to run unzip on "%s"\n' "$archive_path" >&2
exit 1
fi
스크립트에서(아마도 첫 번째 명령문으로) 사용하는 경우 set -e
명령(조건문의 일부가 아닌)이 0이 아닌 종료 코드와 함께 반환되면 자동으로 종료됩니다.
set -e
# The following would terminate the script if it failed:
unzip "$archive_path"
추가된 "편집"에 관해: 여기서 하고 있는 작업은 Zip 아카이브를 선택하기 위한 파일 브라우저 도구 또는 파일 관리자를 구현하기 시작하는 것입니다. 실제로 이 코드를 어떤 용도로 사용하려는지에 따라 이는 과잉일 수도 있습니다.
답변4
사용자가 다음 중 하나를 선택하도록 하려는 경우기존의나는 사용자가 정확히 알지 못할 수도 있는 파일 이름을 작성하는 대신 목록에서 선택할 수 있도록 select
대신 파일을 사용했습니다 .read
select package1 in *.zip; do
break;
done
echo "$package1"
사용자에게 목록이 표시되고 번호를 입력합니다.