중첩된 bash if then else 스크립트가 예상대로 URL과 파일을 분리하지 않음

중첩된 bash if then else 스크립트가 예상대로 URL과 파일을 분리하지 않음

현재 파일용 스크립트와 URL용 스크립트 두 개가 있는데 이를 결합하고 싶습니다.

아래 스크립트가 구성되어 있습니다. 매개변수가 전달되면 URL이면 함수를 실행하고, 매개변수로 전달된 파일이면 다른 함수를 실행하고 싶습니다. 가끔 와일드카드를 사용하여 여러 파일을 전달하는 경우가 있습니다.

@Q를 사용하여 특수 문자를 이스케이프합니다. 내 특별한 경우에는 참조가 실패했습니다.

실행해 보면 두 기능이 모두 실행되는데 정확한 배열을 알 수 없습니다.

예시 1:script.sh "https://demo.io/download.php?id=123456"

예시 1:script.sh "http://test.io/download.php?id=54321"

예시 3:script.sh "John's file.mp4"

예시 4:script.sh "John's file*.mp4"

#!/bin/bash
if [ "$#" -eq 0 ]
          then
echo "no argument supplied"
else
if [[ $1 != http?(s):// ]]; then
        echo "Invalid URL, must be a file"
echo "$# arguments:"
    for x in "$@"; do
            foo_esc="${x@Q}"
            echo "file is "$foo_esc""
            mediainfo "$foo_esc"
    done
fi
echo "$# arguments:"
for y in "$@"; do
        file=$(wget --content-disposition -nv "$y" 2>&1 |cut -d\" -f2)
        echo "output is "$file""
        mediainfo "$file"
    done
fi

답변1

논리는 다음을 사용하도록 조정될 수 있습니다 elif.

if A; then
  : do something for condition A
elif B; then
  : do something for condition B
else
  : do something else
fi

A// 부분을 명령으로 바꾸세요 .B:

for(원래 사용되었던) 중첩 메서드는 두 번째 루프가 중첩된 if 블록의 일부가 되도록 위로 이동하는 경우에도 작동 합니다 else.if A; then :; else if B; then :; else :; fi; fi

그 외에도 bash의 @Q매개변수 확장은 일반적으로 명령에 인수로 전달하려는 것이 아닙니다. foo_esc="${x@Q}"; mediainfo "$foo_esc"제대로 작동하지는 않지만 mediainfo "$x"작동할 것입니다. 매개변수를 스크립트에 전달할 때 와일드카드를 사용하려면 와일드카드를 인용하지 마십시오( script "John's file*.mp4"-> ) script "John's file"*.mp4.

이를 수행하는 방법은 항상 여러 가지가 있습니다. Bash를 사용하면 매개변수를 배열에 복사한 다음 배열에서 실행할 수 있습니다 (테스트되지 않았 으므로 로 변경되었는지는 mediainfo모릅니다 ).wgetcurl

#!/bin/bash
echo >&2 "$# argument${2+s}"      # This will look odd when $# is 0
while [[ ${1+1} ]]; do            # Funny way of writing [[ $# -gt 0 ]]
  case $1 in
    (http:// | https://) echo >&2 "${1@Q} looks like a URL"
      file=$(curl -fOJL -w '%{filename_effective}' "$1") &&
      array+=("$file");;
    (*) echo >&2 "${1@Q} is not a URL, checking if available locally"
      { [[ -f "$1" ]] || [[ -d "$1" ]]; } &&
      array+=("$1");;
  esac
  shift
done
[[ ${#array[@]} -gt 0 ]] &&       # The while loop placed arguments into array
mediainfo "${array[@]}"           # now run command if array is not empty

답변2

info.sh에 저장할 수 있습니다.

#!/bin/bash

url_info() {
    url=$1
    file=$(wget --content-disposition -nv "$url" 2>&1 | cut -d\" -f2)
    echo output is "$file"
    mediainfo "$file"
}

file_info() {
    file=$1
    file_esc="${file@Q}"
    echo file is "$file_esc"
    mediainfo "$file_esc"
}

# Error if no arguments supplied
if [[ $# -eq 0 ]];
then
    echo "no argument supplied"
    exit 0
fi

# Loop over arguments and call appropriate function
for arg in "$@";
do
    if [[ $arg == http* ]];
    then
        url_info "$arg"
    else
        file_info "$arg"
    fi
done

그 다음에

chmod +x info.sh
./info.sh "http://example.com" "Some file.mp4"

답변3

문을 사용하면 잘 작동합니다 elif.

#!/bin/bash
if [ "$#" -eq 0 ]
          then
        echo "no argument supplied"
elif [[ $1 != *http?(s)://* ]]; then
        echo "Invalid URL, must be a file"
        echo "$# arguments:"
    for x in "$@"; do
            foo_esc="${x@Q}"
            echo "file is "$foo_esc""
            mediainfo "$foo_esc"
    done
else
        echo "$# arguments:"
for y in "$@"; do
        file=$(wget --content-disposition -nv "$y" 2>&1 |cut -d\" -f2)
        echo "output is "$file""
        mediainfo "$file"
    done
fi

관련 정보