ubuntu 语法错误:意外的"("--bash脚本中带有!(*. sh)[重复]

nzk0hqpo  于 2023-01-29  发布在  其他
关注(0)|答案(3)|浏览(189)
    • 此问题在此处已有答案**:

Difference between sh and Bash(11个答案)
4天前关闭。
我想运行一个sh文件:

#!/bin/bash
for f in !(*.sh); do
    ffmpeg -i "$f" -vf yadif=0:-1 -threads 0 -c:v libx264 -pix_fmt yuv420p \
        -r 29.97 -b:v 3000k -s 1280x720 -preset:v slow -profile:v Main \
        -level 3.1 -bf 2 -movflags faststart /mnt/media/out-mp4/"${f%.mxf}.mp4"
    rm $f
done

但是,我得到了以下错误:

2: task1.sh: Syntax error: "(" unexpected

如果我直接在命令行上尝试,它可以完美地工作。
已检查路径和权限
你知道会发生什么吗?

mqkwyuun

mqkwyuun1#

这不是一个“sh文件”--它是一个bash脚本,如果你用sh yourscript运行它,它将无法工作(因为你试图使用的shell特性extglobs在POSIX sh中不受支持);它只需要用bash yourscript运行,或者在用#!/bin/bash启动时用./yourscript运行(实际上是这样),因此将其描述为“sh文件”会产生误导,而且,即使使用bash,也需要打开扩展的globbing特性。
最直接的问题是!(*.sh)不是常规的glob语法;它是extglob扩展名,默认情况下不可用。您可能有一个.bashrc或类似的配置文件,可以为交互式shell启用此扩展名,但这不适用于脚本。

shopt -s extglob

...以启用这些功能。
清理后,脚本可能如下所示:

#!/bin/bash

shopt -s extglob

# putting settings in an array allows unescaped newlines in definition
# also sorted to make it easier to find things.
settings=(
  -b:v 3000k
  -bf 2
  -c:v libx264
  -level 3.1
  -movflags faststart
  -pix_fmt yuv420p
  -preset:v slow
  -profile:v Main
  -r 29.97
  -s 1280x720
  -threads 0
  -vf yadif=0:-1
)

for f in !(*.sh); do
    ffmpeg "${settings[@]}" -i "$f" \
      /mnt/media/out-mp4/"${f%.mxf}.mp4" && rm -- "$f"
done

请注意以下更改,包括格式设置:

  • shopt -s extglob在扩展glob之前位于自己的行上。
  • rm仅在ffmpeg成功时运行,因为这些命令之间的分隔符是&&,而不是;或空换行符。
  • 传递给rm--参数告诉它将所有未来的参数(在本例中是"$f"的内容)视为文件名,即使它以破折号开头。
  • rm"$f"参数位于双引号内。
ar7v8xwq

ar7v8xwq2#

您需要在脚本中启用扩展的globbing:

shopt -s extglob

还要确保您没有在其他脚本中运行该脚本,例如,通过调用sh script.sh

4dc9hkyq

4dc9hkyq3#

我认为您正在运行这个脚本sh code.sh,这意味着您正在使用sh来运行脚本,但是第一行(#!/bin/bash)暗示它是为bash编写的。
在某些系统上,shbash是相同的,但在其他系统上则不同;并且,当作为sh调用时,Bash会关闭一些非POSIX特性,因此使用正确的shell和正确的调用非常重要。
使用bash code.sh或更好的方法,使脚本可执行(chmod a+x code.sh),然后直接运行它(./code.sh

相关问题