0

At the moment I have two scripts, one for files and one for urls and I want to combine them.

The below script is combined. When an argument is passed, I want it to perform one function if it is a url, and another if it is a file that is passed as an argument. Sometimes I will pass multiple files using a wildcard.

I use @Q in order to escape special characters. In my particular case quotes fail.

At the moment when I run it, both functions are performed and I can't figure out the correct arrangement.

Example1: script.sh "https://demo.io/download.php?id=123456"

Example1: script.sh "http://test.io/download.php?id=54321"

Example3: script.sh "John's file.mp4"

Example4: 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

3 Answers 3

1

The logic could be adjusted to use elif:

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

Replace A/B/: sections with your commands.

The nested approach (as used originally) would also work if the second for loop was moved up to be part of the nested if's else block: if A; then :; else if B; then :; else :; fi; fi.

Other than that: bash's @Q parameter expansion generally isn't what you want to pass as an argument to a command. foo_esc="${x@Q}"; mediainfo "$foo_esc" won't work correctly, but mediainfo "$x" will. To use wildcards when passing arguments to the script, don't quote the wildcard: script "John's file*.mp4" -> script "John's file"*.mp4.

There's always more than one way to do it. With bash, you could copy arguments to an array, then run mediainfo on the array (untested, don't know wget so changed to curl):

#!/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
1
  • 1
    I haven't tested your array, but elif is what i was missing. Regarding @Q it is probably not ideal, but works for my testing. My case is passing the filenames to a python script. It requires arguments in quotes and is generally confused by apostrophes and spaces, especially when used together even with multiple levels of quotes. Another means of escaping special characters would be be gladly received, but this is what I found that works. Commented Jul 28, 2020 at 6:43
1

You can save this in 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

then

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

This is working correctly using elif statements.

#!/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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.