4

背景:

我正在编写一个必须接收这些参数的 bash 脚本:

  1. 文件名(包含一组规则的文件)
  2. 文件名列表(要处理的文件,可以使用通配符)
  3. 目标文件夹(将存储处理后的文件版本)

理论上有 3 个参数,但实际上第二个参数会扩展,因此如果通配符匹配多个文件,则参数的实际数量会有所不同:

当我打电话

./myscript  file.conf *.data dest_foder

*.data扩展为与通配符匹配的尽可能多的文件,因此它相当于:

myscript file.conf this.data that.data so.data dest_foder

在处理之前,我需要验证最后一个参数是文件夹而不是文件。

问题

如果我省略目标文件夹,例如:

myscript file.conf *.data

验证?# -ge 3通过是因为通配符返回了多个项目,并且如果恰好存在与通配符匹配的文件夹,例如this_is_a_folder.data,那么展开是这样的:

myscript file.conf this.data that.data so.data this_is_a_folder.data

该脚本将工作,但以非预期的方式......它将处理this.data, that.data and so.data文件的处理版本并将其放入文件夹中this_is_a_folder.data

问题

  • 我该如何避免呢?
  • 如何验证目标文件夹是作为参数显式传递的,而不是第二个参数中通配符扩展的产物?

在将文字“* .data”参数扩展为匹配的文件名之前,我找不到读取文字的方法。

澄清:

我知道如何阅读最后一个论点。

  • 但是我怎么知道最后一个参数是明确通过还是产品是通配符扩展?
4

2 回答 2

5

您不能这样做,因为 shell 在您的脚本启动之前会扩展命令行中的任何通配符。当您进入./myscript file.conf *.data dest_fodershell 时,这实际上只是 的简写./myscript file.conf this.data that.data so.data dest_foder,而不是不同的命令。

如果您需要将通配符作为实际参数传递给命令,则需要引用或转义它。像./myscript file.conf '*.data' dest_foder或之类的东西./myscript file.conf \*.data dest_foder。或者,使最后一个参数成为强制性参数,或将其转换为选项 ( -d dest_folder),这样预扩展的文件列表就不会出现问题。

换句话说:如果您不必在 grep 模式中引用/转义通配符,那将非常方便;但是您必须这样做,因为该grep命令无法以未扩展的形式获取其参数。如果 的作者grep无法弄清楚如何使他们的命令更方便,那么您将无法做到...

于 2013-08-05T14:59:52.850 回答
1

您的脚本无法知道,因为它是由 shell 传递参数的,并且它不知道调用进程的状态。为什么不

  1. 重新排序您的参数,以便可变长度参数排在最后
  2. 使用命令行标志,例如 --dest/-d DEST_DIR

这将更符合 UNIX 工具约定。

于 2013-08-05T14:57:23.110 回答