ネストされた bash if then else スクリプトが期待どおりに URL とファイルを分離しない

ネストされた bash if then else スクリプトが期待どおりに URL とファイルを分離しない

現在、ファイル用のスクリプトとURL用のスクリプトが2つあります。これを組み合わせたいです。

以下のスクリプトが構成されています。パラメータが渡された場合は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(元々使用されていた)ネストメソッドは、2番目のループがネストされたifブロックの一部になるように上に移動した場合にも機能しますelseif 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

関連情報