【问题标题】:find hidden and non-hidden files via shell script通过 shell 脚本查找隐藏和非隐藏文件
【发布时间】:2020-06-15 11:50:02
【问题描述】:

我编写了一个小 shell 脚本,它在容器启动过程中创建了多个扩展名为 .dist 的文件的副本,而没有扩展名。

#! /bin/sh

path=$(pwd)
echo $path
shopt -s dotglob
for file in ./*.dist; do

    filename=$(basename -- "$file")
    #echo $filename
    name="$path/${filename%.*}"
    #echo $name

    if [ -a "$name" ]; then
        echo "$name already exists."
    else
        echo "copy $file to $name"
        cp -f "$file" "$name";
    fi
done;
shopt -u dotglob

在本地,它在我的 MacO 上运行良好,但在容器中,Alpine 不使用 bash,而是使用 sh 作为 shell,并且它不知道“shopt”命令。

当您使用 bash 时,“shopt”是我可以安装的东西还是只是一个可用的命令?

如果 shopt 不可用,我如何更改我的脚本,让 for 循环查找隐藏文件(前面带有点)以及普通文件?

示例,应该都可以找到: phpstan.neon.dist .php_cs.dist

【问题讨论】:

  • 你试过比较ls *.distls -a *.dist吗?您可以将其与diff 进行比较
  • 究竟如何?我的 for 条件的语法是什么?
  • 如果您真的想要 bash(而不是修复脚本以在 Busybox 中运行),您是否尝试过 apk add bash
  • 不,我肯定更喜欢在 sh 中工作的脚本。添加 bash 只是最后的解决方案。
  • for file in ./*.dist .*.dist?

标签: docker sh alpine


【解决方案1】:

POSIX shell specificationPatterns Used for Filename Expansion 有特定的规则,注意:

如果文件名以 ('.') 开头,则应使用 作为模式的第一个字符或紧跟在 字符之后显式匹配 。前导 不应与 [...] 特殊字符匹配。

GNU Bash The Shopt Builtin 修改了这条规则:

dotglob:如果设置,Bash 会在文件名扩展结果中包含以“.”开头的文件名。文件名“.”和“..”必须始终明确匹配,即使设置了dotglob

因此,特定于 Bash 的 dotglob * 模式几乎类似于 POSIX * .*,除了几个特定的​​极端情况:POSIX .* 将匹配当前目录和父目录 ...,如果没有非隐藏文件名,那么你会在输出中得到一个文字*

您的“文件,可能以.dist 结尾的隐藏文件”规则与当前目录完全不匹配。您可以防止*.dist 不匹配,或防止存在一个真正的文件,字面上命名为*.dist,方法是使用test -f 仅处理已知存在的文件。

for file in *.dist .*.dist; do
  if test -f "$file"; then
    ...
  fi
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-24
    • 2015-08-04
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多