2015-12-18 31 views
1

我有一个bash脚本,它将一堆命令放在一个文本文件中。然后将其cat的文件转换为sh来运行这些命令。我想要做的只是在目录不存在的情况下运行命令。尝试将管道命令转换为if语句

下面是我:像这样的东西

的文本文件:

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 

换句话说,我想跳过企图使目录,如果路径已经存在。

+2

无法将命令输入到“if”中。你的项目听起来过于雄心勃勃。获得更简单的版本,并确定它是否真的值得重建shell脚本范例;-)。对于dir存在的传统测试是'if! [[-d“$ dir”]];那么mkdir -p“$ dir”; fi'。祝你好运。 – shellter

+0

问题不是你不能通过管道传递一个'if'语句(你可以),这就是你真的需要一个循环。 – chepner

+0

@chepner:你*可以*管道到'if'语句!?酷,你可以在这里作为评论给出一个1/2内胆的例子吗?谢谢 – shellter

回答

1

我不是,如果你想检查文件或目录的存在..清楚,但这里是如何把它:

运行命令的文件是否存在:

[ -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 
+0

这是最有帮助的。我实际上是这样使用的: '[-d/path/to/dir] || mkdir/path/to/dir' 同样,如上所述,我实际上并没有使用mkdir,但是我能够合并这个答案,并且我使用'||'而不是'&&',因为我只希望它运行如果路径不存在。 谢谢! – VanCityGuy

3

更新:该OP自澄清,使用mkdir只是一个例子,而他需要一个通用机制,有条件地从一个文本文件,其中包含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,如果该目录不存在
  • eval "$cmd $path"然后执行该行;注意在这里使用eval的安全性不如管道到sh安全 - 在这两种情况下,您都必须信任代表命令的字符串。 (从当前的Bash shell使用eval意味着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 
+0

非常感谢你,这很好理解,但我实际上并没有使用mkdir,我使用的另一个脚本基本上是作为mkdir运行的,但在我们的内部网络上工作。该脚本可悲的是没有-p标志,但这又是对未来有用的信息! – VanCityGuy

+1

@VanCityGuy:我很高兴你找到了解决方案,我的答案仍然有帮助。将来,请从头说明所有约束条件,以及样本输入的哪些方面是偶然的。我在我的答案顶部添加了一个通用解决方案,希望能够涵盖您的用例。 – mklement0

0

编写您自己的mkdir函数。

假设你的文件没有在任何地方使用mkdir -p这应该工作。

mkdir() { 
    for dir; do 
     [ -d "$dir" ] || mkdir "$dir" 
    done 
} 
export -f mkdir 

sh < file 
+0

谢谢你的建议,但它稍微超出了我。看起来很有趣,但我必须做一些研究来编写我自己的功能,这可能对其他项目非常有用。 谢谢! – VanCityGuy