1

I am trying to make a simple bash script for a command so i can make it reusable for me the command has been taken from another post to convert videos with ffmpeg then upload.

Here is what i have so far.

#!/bin/bash
MOVIES=$1
EXT=$2
BUCKET=$3
find "$MOVIES" -name "*.$EXT" -exec sh -c 'ffmpeg -i "$0" -c:v libx264 -crf 22 -c:a libfaac -movflags faststart "${0%%.mov}.mp4" && s3cmd put "${0%%.mov}.mp4" "$BUCKET""$(basename "${0%%.mov}.mp4")"' {} \;
exit;

I am having issues with the third var if i run it like this.

sh batch.sh ~/Documents/screengrabs/ mov s3://bucket/

I am getting a error it encodes properly.

ERROR: Parameter problem: Destination must be S3Uri. Got: file://49A22352-9F41-48B9-BF97-610CBF699025-630-0000055828D0D55F.mp4

This means it is not parsing the $3 parameter $BUCKET properly.

Any help this is my first bash script attempt.

Thanks

Update still not working

#!/bin/bash
MOVIES="$1"
EXT="$2"
BUCKET="$3"

find "$MOVIES" -name "*.${EXT}" -exec sh -c 'ffmpeg -i "$0" -c:v libx264 -crf 22 -c:a libfaac -movflags faststart "${0%%.mov}.mp4" && s3cmd put "${0%%.mov}.mp4" "${BUCKET}/sam.mp4"' {} \;

exit;

WORKING

#!/bin/bash
MOVIES=$1
EXT=$2
export BUCKET=$3
find "$MOVIES" -name "*.$EXT" -exec sh -c 'ffmpeg -i "$0" -c:v libx264 -crf 22 -c:a libfaac -movflags faststart "${0%%.mov}.mp4" && s3cmd put "${0%%.mov}.mp4" "$BUCKET""$(basename "${0%%.mov}.mp4")"' {} \;
exit;
10
  • I think using variables MOVIES,EXT,BUCKET like "*.${EXT}", "${BUCKET}" will work instead of $BUCKET,$EXT. Commented Sep 30, 2014 at 13:20
  • Still no luck if i hard code s3://bucket/ instead on the ${BUCKET} option it works Commented Sep 30, 2014 at 13:34
  • The command line arguments should be in quotes too like this: BUCKET="$3" Commented Sep 30, 2014 at 13:37
  • 1
    Quoting a single parameter expansion on the RHS of an assignment is unnecessary Commented Sep 30, 2014 at 13:39
  • What does echo "$BUCKET" output if you put it just before the find command? Commented Sep 30, 2014 at 13:41

2 Answers 2

1

The problem is that $0 is the name of the script that is executed (in this case a temporary file created by sh from the argument to -c), not the first argument to the resulting script. Note that the error message does not mention a file with sam in the name, so it is being generated by the ${0%%.mov}.mp4 argument to s3cmd, not the one that uses $BUCKET. Replace it with $1. Also, you need to export BUCKET so that the shell started by find has access to it. (The literal string $BUCKET, not its value, is passed to sh via its -c option because the string is rightly single-quoted.)

(UPDATE: as Etan pointed out, $0 is correct.)

#!/bin/bash
MOVIES=$1
EXT=$2
export BUCKET=$3
find "$MOVIES" -name "*.$EXT" -exec sh -c 'ffmpeg -i "$0" -c:v libx264 -crf 22 -c:a libfaac -movflags faststart "${1%%.mov}.mp4" && s3cmd put "${0%%.mov}.mp4" "$BUCKET""$(basename "${0%%.mov}.mp4")"' {} \;
exit;

In bash 4, however, I would just write

#!/bin/bash
MOVIES=$1
EXT=$2
BUCKET=$3

shopt -s globstar
for movie in "$MOVIES"/**/*."$EXT"; do
    mp4movie=${movie%%.mov}.mp4
    ffmpeg -i "$movie" -c:v libx264 -crf 22 -c:a libfaac -movflags faststart "$mp4movie" &&
      s3cmd put "$mp4movie" "$BUCKET/$mp4movie"
done

This is much easier to get right than trying to cram a small script into a single string for sh -c.


Manual recursive search with bash 3.2:

process_file () {
    movie=$1
    mp4movie=${movie%%.mov}.mp4
    ffmpeg -i "$movie" -c:v libx264 -crf 22 -c:a libfaac -movflags faststart "$mp4movie" &&
      s3cmd put "$mp4movie" "$BUCKET/$mp4movie"
}

process_directory () {
    dir=$1
    for name in "$dir"/*; do
        if [[ -d "$name" ]]; then
            process_directory "$name"
        elif [[ -f $name && $name = *.$EXT ]]; then 
            process_file "$name"
        fi
    done
}

MOVIES=$1
EXT=$2
BUCKET=$3
process_directory "$MOVIES"
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks Chepner tried to get this to work but i just get this error /Users/user/Documents/screengrabs//**/*.mov: No such file or directory sorry i have no knowledge of bash scripts going to watch some tutorials now
When using -c the first non-option argument to sh is set to $0. In normal usage that is the script name but not with an explicit set of non-script non-option arguments. sh -c 'echo "\$0:$0=$@"' foo bar baz outputs $0:foo=bar baz.
Thanks, Etan. I should have double-checked that. I would edit my answer, but in light of the odd file: URL, I'm not sure what edit to make.
@user1503606 That error implies you are using bash 3.2 (and the directory implies you are using Mac OS X, whose default bash is indeed 3.2), so globstar is unavailable unless you install bash 4 yourself.
@chepner i have updated the answer to show what did work the export seemed to do the trick i have no idea why going to do some research while my videos upload.
|
0

@chepner's answer about using a "native" shell script is a good one. That being said, and as I just posted in a comment on the OP, I believe the issue here is simply a variable scope issue.

If you edit the script to use "$1" instead of "$BUCKET" in the script passed to sh -c and add "$BUCKET" between the {} and \; I believe the script will work (though I haven't fully evaluated the script in other respects).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.