Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell “为什么可以?”$路径“/{,.}*包括"*&引用;结果如何?_Shell_Sh_Glob - Fatal编程技术网

Shell “为什么可以?”$路径“/{,.}*包括"*&引用;结果如何?

Shell “为什么可以?”$路径“/{,.}*包括"*&引用;结果如何?,shell,sh,glob,Shell,Sh,Glob,我有一个bash脚本,其中我使用 for x in "$path/"{.,}*; do do some stuff here done 这会在所有文件和目录上循环(这就是我想要的), 但是它也给了我一个不存在的文件*。 我在android上使用终端仿真器,所以可能会出错。 我正在寻找一个shell解决方案,因为我没有像sed这样的大多数“普通Linux”命令。如果您的shell真的是Bash(如问题最初所述) 运行以下命令: shopt -s nullglob 将禁用在没有未展开

我有一个bash脚本,其中我使用

for x in "$path/"{.,}*; do
    do some stuff here  
done
这会在所有文件和目录上循环(这就是我想要的), 但是它也给了我一个不存在的文件
*
。 我在android上使用终端仿真器,所以可能会出错。 我正在寻找一个shell解决方案,因为我没有像sed这样的大多数“普通Linux”命令。

如果您的shell真的是Bash(如问题最初所述) 运行以下命令:

shopt -s nullglob
将禁用在没有未展开匹配项的情况下保留全局的默认行为。请注意,这可能会产生令人惊讶的副作用:设置
nullglob
时,
ls-l*.NotFilenamesHaveThisSuffix
将与
ls-l
完全相同


也就是说,你可以做得更好:

shopt -s dotglob
for x in "$path/"*; do
    printf 'Processing file: %q\n' "$x"  
done
由于设置了
dotglob
,将查找所有隐藏的文件,而根本不需要使用
{、}
习惯用法,并且还具有一贯忽略
的好处。


如果您的Shell是
ash
mksh
实际上,在Android设备上找到bash是很常见的。如果您有一个基线POSIX shell,那么下面的内容将更加健壮

for x in "$path"/* "$path"/.*; do
  [ -e "$x" ] || continue                      # skip files that don't exist
  basename=${x##*/}                            # find filename w/o path
  case $basename in "."|"..") continue ;; esac # skip "." and ".."

  echo "Processing $x" >&2
  : ...put your logic here...
done

使用编辑器中的
{}
按钮,或在每行前面添加四个空格缩进,用于多行代码块。也就是说,您的目标只是确保隐藏文件包含在glob表达式中,对吗?告诉shell这正是您想要的更容易。(也就是说,
*
在标准Linux文件系统上总是有匹配项——即使这些匹配项只是目录
——所以我很好奇您的平台会得到相反的结果)…也就是说,您的shell真的很强大吗,或者它类似于busybox ash(它只支持真正的POSIX sh语法,不支持bash扩展)?看起来可能是ash或mksh,而不是bash。如果是这种情况,您可能应该调整问题的标记。至于{}按钮或缩进,谢谢,我只有一个文本框,没有编辑器按钮,我将尝试记住四个缩进。事实上,我也想要隐藏文件,平台是一个终端仿真器应用程序,其中包含posix bash的子集(如果这是正确的术语),我必须编写自己的basename。例如,我已经使用了-e解决方案,但我希望有一个解决方案不会在列表中包含。*。但我可以忍受这种行为。事实上我不明白。和。。您能解释一下为什么。*可能会出现在列表中吗?如果没有以
开头的文件,并且您的shell没有在输出中无条件地包含
。(这意味着shell肯定不是bash,在全局搜索
*
时会将这些作为结果包含在内),那么它就会出现在列表中。这是因为当glob不匹配时,shell的默认行为是保留不匹配的模式。这样,,
ls-l*.txt
为您提供了
*.txt:不存在这样的文件
,而不是像
ls-l
那样没有参数,并显示当前目录中所有文件的列表,即使这些文件都不匹配全局文件。请记住,大括号扩展不会全局化--无论这些文件是否存在,都会发生这种情况。因此,
{.,}*
与分别传递
*
*
完全相同,并且它们中的每一个都作为一个独立的全局表达式进行计算(如果不匹配,则留在参数列表中)…无论如何,如果您不希望
*
在列表中,即使它没有扩展到任何内容,解决方案是使用shell(像bash!),支持
nullglob