BASH는 가능한 파일을 나열하고 하나를 선택합니다.

BASH는 가능한 파일을 나열하고 하나를 선택합니다.

bash 스크립트를 실행하고 가능한 파일을 파일 선택 옵션으로 나열한 다음 scp를 통해 해당 파일을 대상으로 전송할 수 있기를 원합니다.

scp 부분은 괜찮지만 파일 목록을 가져오고 파일을 선택하는 방법은 나에게 어려운 문제입니다...

$ ./script
Please select a file.
[0] ~/Desktop/ScreenShot-04-06-19-01:02:33.png
[1] ~/Desktop/ScreenShot-04-06-19-01:03:33.png
[2] ~/Desktop/ScreenShot-04-06-19-01:04:33.png
Enter File Index ID: 

답변1

또 다른 방법은 bash에서 선택을 사용하는 것입니다.

$ cat myscript
PS3="Enter File Index ID: "
echo "Please select a file."
select file ; do
  [ "$file" ] &&
   {
     echo "$file"
     break
   } ||
   {
     echo "bad choice"
     break
   }
done

당신은 이것을 다음과 같이 부릅니다:

myscript ~/Desktop/*.png

추신: 스크립트는 명령이므로 스크립트 이름을 myscript로 바꿉니다.
바라보다man script

답변2

사용자가 여러 파일 경로 이름 중에서 선택할 수 있는 대화형 메뉴를 제공하려면 bash다음과 같은 것을 사용할 수 있습니다.

#!/bin/bash

files=( "$HOME/Desktop/ScreenShot-"*.png )

PS3='Select file to upload, or 0 to exit: '
select file in "${files[@]}"; do
    if [[ $REPLY == "0" ]]; then
        echo 'Bye!' >&2
        exit
    elif [[ -z $file ]]; then
        echo 'Invalid choice, try again' >&2
    else
        break
    fi
done

# use scp to upload "$file" here

여기서는 bash명령문을 사용하여 select메뉴를 제공하고 PS3레벨 3 프롬프트를 사용하여 사용자 정의 프롬프트를 제공합니다.

사용자는 0프롬프트에 입력하여 목록에서 파일을 선택하지 않고 스크립트를 종료할 수 있습니다. 잘못된 응답이 제공되면 사용자에게 파일을 선택할 수 있는 또 다른 기회가 제공됩니다. 메뉴를 다시 표시하려면 메시지가 나타나면 를 누르십시오 Enter.

(사용자가 입력한 실제 값)이 비어 있을 때 select스크립트가 종료 되고 (배열에서 선택한 값)이 비어 있을 때 재시도 하는 한 루프 내부 논리가 어떻게 공식화되는지는 실제로 중요하지 않습니다. 또 다른 선언 본문은 다음과 같습니다.$REPLY0$fileselect

if [[ $REPLY == "0" ]]; then
    echo 'Bye!' >&2
    exit
elif [[ -n $file ]]; then
    break
fi

echo 'Invalid choice, try again' >&2

파일 이름은 Shell glob을 통해 명명된 배열에 삽입됩니다. 다음을 사용하여 스크립트의 명령줄에서 관련 파일을 가져올 수도 있습니다.

files=( "$@" )

POSIX 셸에서는 일반적으로 명명된 배열이나 에 액세스할 수 없습니다 select. 대신 다음과 같은 작업을 수행할 수 있습니다.

#!/bin/sh

set -- "$HOME/Desktop/ScreenShot-"*.png

while true; do
    i=0
    for pathname do
        i=$(( i + 1 ))
        printf '%d) %s\n' "$i" "$pathname" >&2
    done

    printf 'Select file to upload, or 0 to exit: ' >&2
    read -r reply

    number=$(printf '%s\n' "$reply" | tr -dc '[:digit:]')

    if [ "$number" = "0" ]; then
        echo 'Bye!' >&2
        exit
    elif [ "$number" -gt "$#" ]; then
        echo 'Invalid choice, try again' >&2
    else
        break
    fi
done

shift "$(( number - 1 ))"
file=$1

# use scp to upload "$file" here

0이는 사용자가 유효한 항목을 입력할 때까지(또는 입력하고 스크립트가 종료될 때까지) 반복되는 상당히 일반적인 입력 루프입니다 . 입력 오류가 발생할 때마다 메뉴가 다시 표시됩니다.

경로 이름은 변형과 마찬가지로 쉘 글로브를 통해 위치 인수 목록으로 가져오지만 bash메뉴는 수동으로 인쇄되며 인쇄되는 각 메뉴 항목에 대해 정수가 증가합니다.

마지막 것은 사용자가 업로드하려는 경로 이름이 되도록 shift위치 매개변수 목록의 시작 부분에 있는 항목을 제거합니다 .$1

대신 명령줄에 제공된 경로 이름을 사용하려면 초기 set명령을 삭제하면 됩니다.

답변3

이것이 bash 스크립트에서 수행하는 방법입니다( shPOSIX 스크립트에서도 사용할 수 있음).

echo 'Please select a file.'

n=0
for img in ~/Desktop/ScreenShot-*.png
do
    n=$((n+1))
    printf "[%s] %s\n" "$n" "$img"
    eval "img${n}=\$img"
done

if [ "$n" -eq 0 ]
then
    echo >&2 No images found.
    exit
fi

printf 'Enter File Index ID (1 to %s): ' "$n"
read -r num
num=$(printf '%s\n' "$num" | tr -dc '[:digit:]')

if [ "$num" -le 0 ] || [ "$num" -gt "$n" ]
then
    echo >&2 Wrong selection.
    exit 1
else
    eval "IMG=\$img${num}"
    echo Selected image is "$IMG"
fi

관련 정보