
사용자에게 특정 유형의 파일을 요청하도록 스크립트를 조정하고 있습니다. 입력한 파일이 특정 파일 형식과 일치하지 않으면 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 루프 테스트 내에서 [[...]]
대신 next를 사용하십시오 . 그러나 이것은 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"
사용자는 목록을 보고 번호를 입력합니다.