我是尝试学习bash编程的脚本语言的新手。
我有一个非常基本的问题。假设我要创建三个文件夹,例如$HOME/folder/
有两个子文件夹folder1
和folder2
。
如果我在shell中执行命令,如
mkdir -p $HOME/folder/{folder1,folder2}
文件夹将与子文件夹一起创建。
如果通过脚本执行相同的操作,我无法获得预期的结果。如果sample.sh
包含
#!/bin/sh
mkdir -p $HOME/folder/{folder1,folder2}
我执行sh ./sample.sh
,将创建第一个文件夹,然后创建一个{folder1,folder2}
目录。不会创建单独的子文件夹。
我的查询是
与终端命令进行比较时,脚本文件的工作原理是什么?即,为什么不一样?
如何让它发挥作用?
答案 0 :(得分:2)
bash
时, sh
的行为会有所不同,以更接近地模仿POSIX标准。其中一个变化是不再识别括号扩展(POSIX中不存在)。您有几种选择:
使用bash ./sample.sh
运行您的脚本。这忽略了hashbang并明确使用bash
来运行脚本。
将hashbang更改为读取#!/bin/bash
,这允许您自己运行脚本(假设您将执行位设置为chmod +x sample.sh
)。
请注意,将其作为sh ./sample.sh
运行仍然会失败,因为仅在将文件本身作为可执行文件运行时才使用hashbang。
不要在脚本中使用大括号扩展。您仍然可以使用更长的方法来避免重复的代码:
for d in folder1 folder2; do
mkdir -p "$HOME/folder/$d"
done
答案 1 :(得分:1)
支持扩张不会发生在sh。
在sh:
$ echo {1,2}
产生
{1,2}
在bash中:
$ echo {1,2}
产生
1 2
使用bash
执行您的脚本,而不是使用sh
,您应该会看到预期的结果。
答案 2 :(得分:1)
这可能正在发生,因为虽然你的标签表明你认为你正在使用Bash,但你可能不会。这是因为第一行:
#/bin/sh
说“使用系统默认shell”。那可能不是bash。试试这个:
#!/usr/bin/env bash
哦,请注意你错过了!在#之后。我不确定这只是一个复制粘贴错误,但你需要!。