【问题标题】:Command is working on terminal but not giving syntax error in bash script命令正在终端上运行,但在 bash 脚本中没有给出语法错误
【发布时间】:2020-09-19 06:38:42
【问题描述】:

下面是我的脚本放在 /usr/bin 中,因为我想让它在全球范围内可用

#!/bin/bash
cd /app/data/zips
rm -rf -i -v !(*.zip)
cd /app/cronscripts/import
> import_output.log
nohup ./import.sh > import_output.log & disown

除了下面给出的行之外,上述脚本中的所有内容都运行良好,但是,直接从终端运行此命令时运行良好。用于删除目录中除 .zip 文件以外的所有文件和文件夹

rm -rf -i -v !(*.zip)

每当我尝试运行此脚本时,都会出现以下错误。

/usr/bin/importdata.sh: line 3: syntax error near unexpected token `('
/usr/bin/importdata.sh: line 3: `rm -rf -i -v !(*.zip)'

我的哪个 bash 输出是:

/bin/bash

操作系统信息:

Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:        18.04
Codename:       bionic

【问题讨论】:

  • 如果我是你,我会做一个find /app/data/zips -depth \! -name "*.zip" -exec rm -rf -i -v '{}' +
  • 你如何运行你的脚本?就像您使用 sh script.sh 而不是使用 bash 运行它
  • 这是用#!/bin/bash替换行后的前两行。它的作用是在 /app/data/zips 中查找所有不具有名称 *.zip(!)的文件或目录,并对它们执行 rm ... 的操作。
  • 任何时候在脚本中使用cd,都需要对其进行某种错误检查——如果cd由于某种原因失败,脚本的其余部分将在错误的位置执行,具有潜在危险的结果。假设rm 命令跑错了地方!
  • @AbdulMoiz 就我个人而言,我根本不喜欢在脚本中使用cd。相反,使用显式路径,例如rm -rf -i -v /app/data/zips/!(*.zip)> /app/cronscripts/import/import_output.log 等。当我需要cd 时,我喜欢使用cd /somedir || { echo "Error changing directory" >&2; exit 1; } 之类的东西(请参阅BashPitfalls #19)。顺便说一句,shellcheck.net 擅长指出此类常见错误。

标签: linux bash shell ubuntu sh


【解决方案1】:

bash 中,!(pattern) 是扩展的全局模式。打开启用该功能的 shell 选项:

shopt -s extglob

shopt 应与您可能依赖的任何其他选项一起出现在脚本开头的单独行中。见 wooledgehttps://mywiki.wooledge.org/glob#Options_which_change_globbing_behavior

extglob 改变了某些字符的解析方式。 shopt -s extglob 和任何后续命令之间必须有一个换行符(不仅仅是分号)才能使用它。您不能在使用它们的组命令中启用扩展 glob,因为整个块在 shopt评估之前被解析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多