【问题标题】:How to delete all except a directory in Makefile?如何删除Makefile中除目录之外的所有内容?
【发布时间】:2019-06-08 06:57:28
【问题描述】:

以下命令集在 linux 提示符下运行。

%cd ${ADIR}/exe; shopt -s extglob; rm -rf !(BDIR)

但它在 Makefile 中不起作用

Linux 命令 - 有效

%cd ${ADIR}/exe; shopt -s extglob; rm -rf !(BDIR)

Makefile 中的命令

        @cd ${ADIR}/exe; shopt -s extglob; rm -rf !\(BDIR\)

制作文件信息

rm: cannot remove `!(BDIR)': No such file or directory

【问题讨论】:

  • 您的 Makefile 命令包含额外的反斜杠。为什么?
  • /bin/sh: -c: line 0: 意外标记附近的语法错误(' /bin/sh: -c: line 0: cd ./adir/exe; shopt -s extglob; rm -r !(BDIR)' make: *** [clean] 错误 2
  • 没有“\”的错误

标签: bash shell makefile sh


【解决方案1】:

您的 Makefile 的问题在于它转义了 (),这使得 shell 会按字面意思解释它们。

第二个问题,

/bin/sh: -c: line 0: syntax error near unexpected token `('

make使用sh执行命令引起的,而不是bash

!(...) 通配符语法(和extglob)仅受 bash 支持,sh 不支持。

您可以显式调用bash

        @bash -c 'cd ${ADIR}/exe; shopt -s extglob; rm -rf !(BDIR)'

但这也不起作用,因为extglob直到下一行输入被读取后才会生效,所以!( )仍然会抛出语法错误。

我们需要一种方法来使用 shell 的一次调用来运行多行命令。不幸的是,make 让这变得不必要地复杂了。

一种可能的解决方案:

SHELL = /bin/bash

...
        @bash -c $$'cd ${ADIR}/exe; shopt -s extglob\nrm -rf !(BDIR)'

这告诉make 使用bash 执行所有配方(不是/bin/sh)。然后我们再次手动运行bash,但使用$'...' 引用命令字符串。这让我们可以编写 \n 来嵌入文字换行符,从而使 extglob / !( ... ) 工作。

我们需要双 $$ 来为 make 转义 $,所以 $'...' 变为 $$'...'

我对这个解决方案不太满意。

【讨论】:

  • 或者,当然,在纯便携式sh 中明显的重新实现; for d in ./*/.; do case $d in ./BDIR/.) continue;; esac; rm -rf "$d"; done
  • 感谢您的帮助,但无法正常工作。我在 bash 环境中工作。主机$ echo $0 bash
  • 我都试过了,@bash -c 'cd ...' 和 SHELL = /bin/bash,但是同样的错误信息
【解决方案2】:

不幸的是,bash 有一个奇怪的行为,因为 shopt 设置在换行之前不会生效,因此同一行上的任何 globbing 都不会识别它。在你的 shell 提示符下试试这个:

$ shopt -s extglob; echo !(BDIR)
bash: !: event not found

那就分两行试试吧:

$ shopt -s extglob
$ echo !(BDIR)
  ...works

不幸的是,这意味着几乎不可能将它与 make 一起使用。

您应该使用 Triplee 评论中建议的 POSIX 兼容版本,并完全避免需要特殊的 shell。

哦,看来答案被删除了。无论如何,请执行以下操作:

foo:
        cd ${ADIR}/exe && for f in *; do \
            case $$f in (BDIR) : ok ;; (*) rm -rf "$$f" ;; esac; \
        done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 2023-01-20
    • 2016-10-09
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多