尝试将管道命令放入 if 语句
Trying with piping commands into an if statement
我有一个 bash 脚本,可以将一堆命令放入文本文件中以创建目录。然后它 cat
将文件转换为 sh
到 运行 命令。如果目录尚不存在,我想做的只是 运行 命令。
这是我的:
包含如下内容的文本文件:
mkdir /path/to/a/directory
mkdir /path/to/another/directory
mkdir /path/to/yet/another/directory
在我的脚本中有这样一行
cat /path/to/my/file.txt | sh
但是有没有办法做这样的事情呢?
cat /path/to/my/file.txt | if path already exists then go to the next, if not | sh
换句话说,如果路径已经存在,我想跳过创建目录的尝试。
我不清楚您是否要检查文件或目录是否存在..但方法如下:
运行 如果文件存在你的命令:
[ -f /path/to/my/file.txt ] && cat /path/to/my/file.txt | sh
或检查目录:
[ -d /path/to/my/directory ] && cat /path/to/my/file.txt | sh
更新:OP 已经澄清使用 mkdir
只是一个例子,他需要一个 generic 机制,根据命令是否引用现有目录,有条件地执行包含 shell 命令的文本文件中的行:
while read -r cmd dir; do [[ -d $dir ]] || eval "$cmd $path"; done < /path/to/my/file.txt
while
循环逐行读取包含 shell 命令的文本文件。
read -r cmd dir
将每一行解析为第一个标记 - 假定为命令(示例输入中的 mkdir
) - 其余部分假定为目录路径。
[[ -d $dir ]]
测试目录路径是否存在,而 ||
仅在测试 失败 时才执行其 RHS,即如果目录 [= =46=]不存在。
eval "$cmd $path"
然后执行该行;请注意,在这里使用 eval
并不比管道 sh
安全 - 在这两种情况下,您都必须信任代表命令的字符串。 (使用eval
从当前的Bashshell意味着Bash会执行命令,而不是sh
,但是我假设这不是问题。)
原答案,基于实际使用mkdir
的假设:
在您的情况下,最简单的方法是将 -p
选项添加到您的 mkdir
调用中,这将安静地忽略创建已存在目录的尝试:
mkdir -p /path/to/a/directory
mkdir -p /path/to/another/directory
mkdir -p /path/to/yet/another/directory
换句话说:mkdir -p
确保目标目录存在,无论那个目录。已经存在或必须创建。
(mkdir -p
仍然会失败,例如当目标路径是 文件 而不是目录时,或者如果您没有足够的权限来创建目录。)
然后您可以简单地将文件传递给 sh
(不需要 cat
和管道,效率较低):
sh /path/to/my/file.txt
如果您不控制输入文件的创建,您可以使用 sed
插入 -p
选项:
sed 's/^mkdir /&-p /' /path/to/my/file.txt | sh
编写您自己的 mkdir
函数。
假设您的文件没有使用 mkdir -p
这应该有效的任何地方。
mkdir() {
for dir; do
[ -d "$dir" ] || mkdir "$dir"
done
}
export -f mkdir
sh < file
我有一个 bash 脚本,可以将一堆命令放入文本文件中以创建目录。然后它 cat
将文件转换为 sh
到 运行 命令。如果目录尚不存在,我想做的只是 运行 命令。
这是我的:
包含如下内容的文本文件:
mkdir /path/to/a/directory
mkdir /path/to/another/directory
mkdir /path/to/yet/another/directory
在我的脚本中有这样一行
cat /path/to/my/file.txt | sh
但是有没有办法做这样的事情呢?
cat /path/to/my/file.txt | if path already exists then go to the next, if not | sh
换句话说,如果路径已经存在,我想跳过创建目录的尝试。
我不清楚您是否要检查文件或目录是否存在..但方法如下:
运行 如果文件存在你的命令:
[ -f /path/to/my/file.txt ] && cat /path/to/my/file.txt | sh
或检查目录:
[ -d /path/to/my/directory ] && cat /path/to/my/file.txt | sh
更新:OP 已经澄清使用 mkdir
只是一个例子,他需要一个 generic 机制,根据命令是否引用现有目录,有条件地执行包含 shell 命令的文本文件中的行:
while read -r cmd dir; do [[ -d $dir ]] || eval "$cmd $path"; done < /path/to/my/file.txt
while
循环逐行读取包含 shell 命令的文本文件。read -r cmd dir
将每一行解析为第一个标记 - 假定为命令(示例输入中的mkdir
) - 其余部分假定为目录路径。[[ -d $dir ]]
测试目录路径是否存在,而||
仅在测试 失败 时才执行其 RHS,即如果目录 [= =46=]不存在。eval "$cmd $path"
然后执行该行;请注意,在这里使用eval
并不比管道sh
安全 - 在这两种情况下,您都必须信任代表命令的字符串。 (使用eval
从当前的Bashshell意味着Bash会执行命令,而不是sh
,但是我假设这不是问题。)
原答案,基于实际使用mkdir
的假设:
在您的情况下,最简单的方法是将 -p
选项添加到您的 mkdir
调用中,这将安静地忽略创建已存在目录的尝试:
mkdir -p /path/to/a/directory
mkdir -p /path/to/another/directory
mkdir -p /path/to/yet/another/directory
换句话说:mkdir -p
确保目标目录存在,无论那个目录。已经存在或必须创建。
(mkdir -p
仍然会失败,例如当目标路径是 文件 而不是目录时,或者如果您没有足够的权限来创建目录。)
然后您可以简单地将文件传递给 sh
(不需要 cat
和管道,效率较低):
sh /path/to/my/file.txt
如果您不控制输入文件的创建,您可以使用 sed
插入 -p
选项:
sed 's/^mkdir /&-p /' /path/to/my/file.txt | sh
编写您自己的 mkdir
函数。
假设您的文件没有使用 mkdir -p
这应该有效的任何地方。
mkdir() {
for dir; do
[ -d "$dir" ] || mkdir "$dir"
done
}
export -f mkdir
sh < file