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.
我正在尝试为命令创建一个简单的bash脚本,所以我可以让它可以重用,我从另一个帖子中获取命令,用ffmpeg转换视频然后上传。
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.
如果我像这样运行它,我遇到第三个var的问题。
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.
这意味着它没有正确解析$ 3参数$ BUCKET。
Any help this is my first bash script attempt.
任何帮助这是我的第一个bash脚本尝试。
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;
2 个解决方案
#1
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.)
问题是$ 0是执行的脚本的名称(在这种情况下是由参数sh创建的临时文件到-c),而不是生成的脚本的第一个参数。请注意,错误消息未提及名称中带有sam的文件,因此它是由s3cmd的$ {0 %%。mov} .mp4参数生成的,而不是使用$ BUCKET的参数。替换为1美元。此外,您需要导出BUCKET,以便由find启动的shell可以访问它。 (文字字符串$ BUCKET,而不是它的值,通过其-c选项传递给sh,因为该字符串是正确的单引号。)
(UPDATE: as Etan pointed out, $0
is correct.)
(更新:正如Etan指出的那样,$ 0是正确的。)
#!/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
然而,在bash 4中,我只会写
#!/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
.
这比试图将一个小脚本塞入sh -c的单个字符串要容易得多。
Manual recursive search with bash
3.2:
使用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"
#2
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.
@chepner关于使用“原生”shell脚本的答案很好。话虽如此,正如我刚刚在对OP的评论中发表的那样,我认为这里的问题只是一个可变范围问题。
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).
如果编辑脚本在传递给sh -c的脚本中使用“$ 1”而不是“$ BUCKET”,并在{}和\之间添加“$ BUCKET”;我相信脚本会起作用(尽管我还没有在其他方面对脚本进行全面评估)。
#1
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.)
问题是$ 0是执行的脚本的名称(在这种情况下是由参数sh创建的临时文件到-c),而不是生成的脚本的第一个参数。请注意,错误消息未提及名称中带有sam的文件,因此它是由s3cmd的$ {0 %%。mov} .mp4参数生成的,而不是使用$ BUCKET的参数。替换为1美元。此外,您需要导出BUCKET,以便由find启动的shell可以访问它。 (文字字符串$ BUCKET,而不是它的值,通过其-c选项传递给sh,因为该字符串是正确的单引号。)
(UPDATE: as Etan pointed out, $0
is correct.)
(更新:正如Etan指出的那样,$ 0是正确的。)
#!/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
然而,在bash 4中,我只会写
#!/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
.
这比试图将一个小脚本塞入sh -c的单个字符串要容易得多。
Manual recursive search with bash
3.2:
使用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"
#2
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.
@chepner关于使用“原生”shell脚本的答案很好。话虽如此,正如我刚刚在对OP的评论中发表的那样,我认为这里的问题只是一个可变范围问题。
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).
如果编辑脚本在传递给sh -c的脚本中使用“$ 1”而不是“$ BUCKET”,并在{}和\之间添加“$ BUCKET”;我相信脚本会起作用(尽管我还没有在其他方面对脚本进行全面评估)。