为什么我的 Bash 代码在使用“sh”运行时会失败?

2023-12-14

我有一行代码在我的终端中运行良好:

for i in *.mp4; do echo ffmpeg -i "$i" "${i/.mp4/.mp3}"; done

然后我将完全相同的代码行放入脚本中myscript.sh:

#!/bin/sh
for i in *.mp4; do echo ffmpeg -i "$i" "${i/.mp4/.mp3}"; done

但是,现在运行时出现错误:

$ sh myscript.sh
myscript.sh: 2: myscript.sh: Bad substitution

根据其他问题,我尝试更改shebang to #!/bin/bash,但我得到了完全相同的错误。为什么我无法运行这个脚本?


TL;DR:由于您使用的是 Bash 特定功能,因此您的脚本必须与 Bash 一起运行,而不是与sh:

$ sh myscript.sh
myscript.sh: 2: myscript.sh: Bad substitution

$ bash myscript.sh
ffmpeg -i bar.mp4 bar.mp3
ffmpeg -i foo.mp4 foo.mp3

See sh 和 Bash 之间的区别。要了解您正在使用哪个 sh:readlink -f $(which sh).

确保 bash 特定脚本始终正确运行的最佳方法

最佳做法是both:

  1. Replace #!/bin/sh with #!/bin/bash(或者您的脚本所依赖的任何其他 shell)。
  2. 运行此脚本(以及所有其他脚本!)./myscript.sh or /path/to/myscript.sh,没有前导sh or bash.

这是一个例子:

$ cat myscript.sh
#!/bin/bash
for i in *.mp4
do
  echo ffmpeg -i "$i" "${i/.mp4/.mp3}"
done

$ chmod +x myscript.sh   # Ensure script is executable

$ ./myscript.sh
ffmpeg -i bar.mp4 bar.mp3
ffmpeg -i foo.mp4 foo.mp3

(有关的:为什么脚本前面要加./?)

的含义#!/bin/sh

shebang 建议系统应使用哪个 shell 来运行脚本。这允许您指定#!/usr/bin/python or #!/bin/bash这样您就不必记住哪个脚本是用哪种语言编写的。

人们使用#!/bin/sh当他们只使用一组有限的功能(由 POSIX 标准定义)来实现最大的可移植性时。#!/bin/bash对于利用有用的 bash 扩展的用户脚本来说非常合适。

/bin/sh通常符号链接到最小的 POSIX 兼容 shell 或标准 shell(例如 bash)。即使在后一种情况下,#!/bin/sh可能会失败,因为bash将以兼容模式运行,如中所述man page:

如果使用 sh 名称调用 bash,它会尝试尽可能模仿 sh 历史版本的启动行为,同时也符合 POSIX 标准。

的含义sh myscript.sh

shebang 仅在您跑步时使用./myscript.sh, /path/to/myscript.sh,或者当您删除扩展程序时,将脚本放入您的目录中$PATH,然后运行myscript.

如果您显式指定解释器,则将使用该解释器。sh myscript.sh将强制它运行sh,不管shebang说什么。这就是为什么改变 shebang 本身是不够的。

您应该始终使用首选解释器运行脚本,因此更喜欢./myscript.sh或每当您执行任何脚本时类似的内容。

对脚本的其他建议更改:

  • 引用变量被认为是很好的做法("$i"代替$i)。如果存储的文件名包含空格字符,则引用的变量将防止出现问题。
  • 我喜欢你使用先进的参数扩展。我建议使用"${i%.mp4}.mp3"(代替"${i/.mp4/.mp3}"), 自从${parameter%word}仅在末尾替换(例如名为foo.mp4.backup).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的 Bash 代码在使用“sh”运行时会失败? 的相关文章

  • 在 bash 中,如何除以两个变量并输出四舍五入到小数点后 5 位的答案? [复制]

    这个问题在这里已经有答案了 我将两个变量作为输入 将它们相除后 我希望将输出四舍五入到小数点后 5 位 我已经尝试过这种方法 gt sum 12 n 7 output scale 5 sum n bc echo output 我的代码没有显
  • 用于获取特定用户 ID 和进程数的 Bash 脚本

    我需要 bash 脚本来计算特定用户或所有用户的进程 我们可以输入 0 1 或更多参数 例如 myScript sh root deamon 应该像这样执行 root 92 deamon 8 2 users has total proces
  • BASH 中的空函数

    我正在使用 FPM 工具创建 deb 包 此工具在从支持的文件中删除包之前 之后创建 不幸的是FPM生成的bash脚本包含这样的函数 dummy 该脚本退出时出现错误 语法错误 意外 BASH 不允许空函数吗 哪个版本的 bash linu
  • 如何回忆上一个 bash 命令的参数?

    Bash 有没有办法回忆上一个命令的参数 我通常这样做vi file c其次是gcc file c Bash 有没有办法回忆上一个命令的参数 您可以使用 or 调用上一个命令的最后一个参数 Also Alt can be used to r
  • 如何在 Bash 中删除字符串的第一部分?

    该代码将给出第一部分 但是如何删除它并获取没有第一部分的整个字符串 echo first second third etc cut d f1 你应该看看info cut 这将解释什么f1 means 实际上我们只需要第二个字段之后的字段 f
  • git log --oneline 提供在管道或重定向到文件时丢失的 HEAD 信息

    当我执行没有管道或文件重定向的 git log oneline 命令时 它会提供有关 HEAD 位置和分支的信息 下面示例中的 master git log oneline color never 8bc8511 HEAD gt day 2
  • 如何在 Bash 脚本中查找数字的阶乘?

    在 shell 脚本中如何查找数字的阶乘 seq s 1 500 bc
  • Python 子进程:无法转义引号

    我知道以前曾问过类似的问题 但它们似乎都是通过重新设计参数的传递方式 即使用列表等 来解决的 但是 我这里有一个问题 因为我没有这个选项 有一个特定的命令行程序 我使用的是 Bash shell 我必须向其传递带引号的字符串 它不能不被引用
  • 在unix、bash中合并csv文件

    我有一些 csv 文件 其格式如下 测试1 csv field port1 a1 0 2 a2 0 3 a3 0 6 测试2 csv field port2 b1 0 5 b2 0 6 b3 0 7 b4 0 1 b5 0 5 测试3 cs
  • 使用转义序列渲染文本(如终端)

    你好 我正在寻找一些库或工具来在文本文件中呈现带有转义序列字符的文本 我不知道如何称呼它 但这是一个例子 echo e abc vdef abc def echo e abc vdef gt tmp xxxxx vi tmp xxxxx 我
  • shell脚本中是否有互斥/信号量机制?

    我正在 shell 脚本中寻找互斥 信号量 并发机制 考虑以下情况 除非 a 用户不关闭共享文件 否则 b 用户应该无法打开 更新它 我只是想知道如何在 shell 脚本中实现互斥量 信号量 临界区等 在 shell 脚本中实现锁定机制 文
  • 将儒略时间戳转换为 UNIX 中的常规时间

    我需要使用 Bash 将 UNIX 中的 Julian 时间戳转换为常规时间戳 在 Tandem OS 上 转换非常简单 例子 212186319010244541 OLSAPP SYSTST 1 gt interprettimestamp
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 需要 sudo 密码的 Bash 脚本

    我正在创建一个 Bash 安装程序脚本 它为 OSX 和 Linux 编译并安装一些库 因为我的脚本中的某些命令 make install apt get install port install 等 需要 sudo 所以我需要用户提供密码
  • 如何并行运行命令列表?

    我有一个包含我要运行的命令行的文件 该文件包含大约 2 000 行 我有 8 个可用核心 是否可以解析文件并启动 8 个进程 然后在其中一个程序完成时从文件中执行另一个进程 我希望这种情况继续下去 直到到达文件末尾 Use GNU并行 ht
  • 在 bash 中快速引用 stdout(即上一个命令的输出)?

    有没有办法快速 例如通过键盘快捷键等 引用写入到 stdout 的上一个命令的输出 例如 如果我这样做 which rails 它回来了 usr local bin rails然后我想在 textmate 中打开该文件 我可以像这样重新输入
  • 从sourceforge下载最新版本

    我正在尝试在 bash 脚本中从 Sourceforge 下载最新版本的graphicsmagick wget q https sourceforge net projects graphicsmagick files latest dow
  • 为什么 RHEL 上的 bash 中 `read -t` 没有超时?

    Why read t在 RHEL5 或 RHEL6 上从管道读取时不会超时 这是我的示例 在从管道读取数据时 我的 RHEL 盒子不会超时 tail f logfile log grep something read t 3 variabl
  • bash 如何识别链接?

    在捕获 href 链接的 bash 脚本中 bash 如何知道 TEXT 是链接而不是典型的字符串 为什么最后当 TEXT www google com 时 TEXT 仍然是一个链接 你能用一个文件做到这一点吗 例如 有一个运行脚本的 点击
  • PDF:在现有 PDF 文件中插入一行文本

    我有一个 PDF 文件 我希望在所有页面 前两页除外 的页脚上添加一行纯文本 不是徽标或类似内容 有谁有一个如何做到这一点的例子 用任何语言 Update 原始 PDF 是用 Scribus 制作的 我可以完全控制它 因此 如果更容易进行查

随机推荐

  • ASP.NET MVC 中的 jQuery AJAX 响应

    甚至不确定这是否是标题问题的正确方式 我知道我的 AJAX 调用都是错误的 这就是我现在正在做的事情 顺便说一句 我正在使用 ASP NET MVC 后端 I use jQuery ajax将一些数据发布到操作 该操作将加载我在响应中捕获的
  • 我可以使用 Box::from_raw 从 Vec::into_boxed_slice 释放内存吗?

    I saw以下代码用于将字节数组返回给 C repr C struct Buffer data mut u8 len usize extern C fn generate data gt Buffer let mut buf vec 0 5
  • 如何用Delphi 5创建Telnet客户端

    如何在 Delphi 5 应用程序中创建 Telnet 客户端 ICSFrancois Piette 的 Internet Component Suite 有一些有用的组件 http www overbyte be eng products
  • MySQL 查询返回重复行

    我有一张桌子mytable像下面这样 product tag lot 1111 101 2 1111 102 5 2222 103 6 3333 104 2 4444 101 2 5555 101 2 5555 102 5 6666 102
  • XPath 中的逻辑或?为什么不是|在职的?

    我有一个 XSLT 模板 它对所有级别的主题进行计数 用于在我拥有的 DITA 项目中用编号来标记这些主题
  • 自定义 Win32 的保存文件对话框

    我正在尝试使用保存文件GetSaveFileName并希望在我的保存文件对话框的底部有几个额外的弹出窗口 以允许用户指定更多选项 我正在尝试遵循MSDN 文档 具体来说资源管理器式定制 关于这个主题 但似乎无法让我的自定义项目出现 我相信我
  • Python Pillow 透明 gif 不起作用

    我正在尝试制作以下图标旋转的 gif 为了尝试实现这一目标 我使用 Pillow 库在 Python 中运行以下代码 from PIL import Image ImageDraw images icon Image open camera
  • Android 点击地图并获取坐标[重复]

    这个问题在这里已经有答案了 我正在尝试制作一个应用程序 一旦用户点击地图 它就会获取该特定点的坐标 除其他外 我还读到 在android中点击地图获取坐标 这似乎是最相关的帖子 但我想要做的是能够点击地图上的任何位置而不是标记 覆盖项目 事
  • JavaScript 闭包和内存泄漏

    我在 Jquery in Action 中读到 JavaScript 闭包可能会导致内存泄漏 意外的闭包可能会产生意想不到的后果 例如 循环引用可能导致内存泄漏 一个典型的例子是创建引用闭包变量的 DOM 元素 从而防止这些变量被回收 有人
  • 将 Unicode 字符串存入 SQLite 数据库

    我需要一些关于将 unicode 字符串插入 SQLite 数据库的 Visual Studio C 代码方面的帮助 下面是我将测试字符串写入数据库的测试代码 string testStr SQLiteConnection mydataCo
  • 将 CommandParameter 从 MenuItem 绑定到父 DataGrid

    如何将命令参数从 MenuItem 绑定到父 Grid DataContext 我有一个带有 ContextMenu 的 DataGrid 将菜单项绑定到 ViewModel 命令 但命令参数始终为 null 我使用 DataGrid 中的
  • R 无法在 ff 过程上分配内存。怎么会?

    我正在使用配备 Intel Xeon 处理器和 24 GB RAM 的 64 位 Windows Server 2008 计算机 我在尝试读取 11 GB gt 2400 万行 20 列 的特定 TSV 制表符分隔 文件时遇到问题 我平常的
  • 如何在 Flutter 应用程序屏幕中显示来自服务器的响应?

    我是颤振新手 我正在尝试在屏幕上显示服务器的响应 我从服务器获取订单历史记录并尝试将其显示在历史记录屏幕上 你该怎么做 void getAllHistory async http post Uri parse https myurlblah
  • 如何使用 Selenium、C# 从 dom 元素获取所有 css 样式

    我的任务是从网页创建最小化的 css 文件 所以我需要来自的价值观所有 css 属性来自所有 dom 元素 但我不知道 如何从特定的 dom 元素获取所有计算的 css 样式 我有以下代码 var chromeOptions new Chr
  • 将 PrimeFaces 添加为 EAR 库时遇到问题

    我想在我的 Java EE 6 Jboss AS 7 1 1Final 应用程序中使用具有以下结构的 PrimeFaces EAR lib primefaces 4 0 jar ejb module jar webbapp1 war web
  • 如何在单击时向元素添加 CSS 类 - React

    如何在单击时将 CSS 类添加到现有 REACT 元素 我创建了一个 JSFiddle https jsfiddle net 5r25psub 在小提琴中 只有当我有以下语句时 代码才有效 this setState color blue
  • PHP从不同时区的服务器获取英国当地时间

    我有一个网络服务器 我不知道时区设置为多少 现在是英国上午 10 49 但是当我运行以下命令时 sTime gmdate d m Y H i s print The time is sTime 服务器返回以下时间 The time is 2
  • 从文本字段中选择粗体和斜体文本

    我怎样才能只选择bold and 斜体字用户在 textField textView 中输入的文本 我们可以制作选定的文本bold 斜体字 下划线以及这三者的任意组合 但反之亦然呢 这不是 Mac OSX 或 iOS 所特有的 任何一种的解
  • 如何阻止其他应用程序使用麦克风?

    我正在开发 android voip 应用程序 我想确定是否有其他应用程序正在使用麦克风 通过这个 我想在使用麦克风时阻止其他应用程序访问麦克风 请任何人有想法 这对我很有帮助 Thanks 最后知道我们可以检查麦克风的可用性 如下所示 p
  • 为什么我的 Bash 代码在使用“sh”运行时会失败?

    我有一行代码在我的终端中运行良好 for i in mp4 do echo ffmpeg i i i mp4 mp3 done 然后我将完全相同的代码行放入脚本中myscript sh bin sh for i in mp4 do echo