语法错误:"("unexpected -- with !(*.sh) in bash 脚本 [英] Syntax error: "(" unexpected -- with !(*.sh) in bash script

查看:42
本文介绍了语法错误:"("unexpected -- with !(*.sh) in bash 脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想运行一个 sh 文件:

I want to run a sh file:

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

但是,我收到以下错误:

However, I get the following error:

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

如果我直接在命令行上尝试,它可以完美运行.

If I try directly on the command line it works perfectly.

路径和权限已经审核

知道会发生什么吗?

推荐答案

这不是sh 文件"——它是一个 bash 脚本.如果您使用 sh yourscript 运行它,它将无法工作(因为 extglobs,您尝试使用的 shell 功能,在 POSIX sh 中不受支持);当以 #!/bin/bash 开头时,它只需要使用 bash yourscript./yourscript 运行(就像它一样).因此,将其描述为sh 文件"是一种误导.而且,即使使用 bash,也需要开启扩展的 globbing 功能.

This is not a "sh file" -- it's a bash script. If you run it with sh yourscript, it will not work (as extglobs, the shell feature you're trying to use, aren't supported in POSIX sh); it needs to be run only with bash yourscript, or with ./yourscript when starting with #!/bin/bash (as it does). Describing it as a "sh file" is thus misleading. Moreover, even with bash, the extended globbing feature needs to be turned on.

您的直接问题是 !(*.sh) 不是常规的 glob 语法;它是 一个 extglob 扩展,默认情况下不可用.您可能有一个 .bashrc 或类似的配置文件,它为交互式 shell 启用此扩展,但这不适用于脚本.运行:

Your immediate issue is that !(*.sh) is not regular glob syntax; it's an extglob extension, not available by default. You may have a .bashrc or similar configuration file which enables this extension for interactive shells, but that won't apply to scripts. Run:

shopt -s extglob

...启用这些功能.

清理后,您的脚本可能如下所示:

Cleaned up, your script might look like:

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

注意除格式之外的以下更改:

Note the following changes, above and beyond formatting:

  • shopt -s extglob 在 glob 展开之前单独一行.
  • rm 仅在 ffmpeg 成功时运行,因为这些命令之间的分隔符是 &&,而不是 >; 或一个空的换行符.
  • 传递给 rm-- 参数告诉它处理所有未来的参数(在这种情况下,"$f" 的内容) 作为文件名,即使它以破折号开头.
  • rm"$f" 参数在双引号内.
  • shopt -s extglob is on its own line, before the glob is expanded.
  • The rm is only run if ffmpeg succeeds, because the separator between those commands is &&, rather than either ; or a bare newline.
  • The -- argument passed to rm tells it to treat all future arguments (in this case, the content of "$f") as a filename, even if it starts with a dash.
  • The "$f" argument to rm is inside double quotes.

这篇关于语法错误:"("unexpected -- with !(*.sh) in bash 脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆