AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 424056
Accepted
user9303970
user9303970
Asked: 2018-02-14 23:15:38 +0800 CST2018-02-14 23:15:38 +0800 CST 2018-02-14 23:15:38 +0800 CST

在双引号变量扩展后使用 shell glob(通配符 (*))

  • 772

我读到在 Bash 中双引号所有变量扩展是最佳实践。我还读到不能*在双引号变量扩展之后立即使用 shell glob (wildcard())。当人们想要使用从变量扩展出来的正则表达式模式的值时,这些情况就会发生冲突。

我有时想将正则表达式与通配符结合起来的原因是为了使我的正则表达式保持最小、更整洁,符合我的个人喜好。

我的特殊问题

我将 phpmyadmin 下载到我的文档根目录并解压缩,但我无法mv通过我放入变量的正则表达式模式重命名它,并且在扩展其变量时可用。这是确切的跟踪:

userName@compName:/var/www/html# ll
total 11336
drwxr-xr-x  3 root root     4096 Feb 14 07:04 ./
drwxr-xr-x  3 root root     4096 Feb 14 06:56 ../
-rw-r--r--  1 root root      612 Feb 14 06:57 index.nginx-debian.html
drwxr-xr-x 12 root root     4096 Dec 23 08:50 phpMyAdmin-4.7.7-all-languages/
-rw-r--r--  1 root root 11589684 Dec 23 14:08 phpMyAdmin-latest-all-languages.zip
userName@compName:/var/www/html# echo $pma
[pP][hH][pP][mM][yY][aA][dD][mM][iI][nN]
userName@compName:/var/www/html# mv "$pma"*/ phpmyadmin/
mv: cannot stat '[pP][hH][pP][mM][yY][aA][dD][mM][iI][nN]*/': No such file or directory

如果我取消对变量扩展的引用,${pma}我确实能够将变量扩展和正则表达式结合起来,如${pma}*,但如果可以的话,毫无例外地遵循最佳实践对我来说很重要。

我的问题

我怎样才能保持变量扩展双引号,但仍然使用带通配符的提取值?

regular-expression filenames
  • 2 2 个回答
  • 1326 Views

2 个回答

  • Voted
  1. Best Answer
    Kusalananda
    2018-02-15T00:09:03+08:002018-02-15T00:09:03+08:00

    如果双引号,保存在变量中的文件名通配模式将不会通配文件名。阻止文件名被通配的是双引号,而不是*末尾的通配符或引号和*.

    我们经常告诉网站上的用户“引用他们的变量”,我们这样做是因为未引用变量的值会经历分词和文件名通配,而这通常不是我们想要的。例如,根据当前目录中存在的文件(并且由于空间的原因,它可能根本无法正常工作) ,密码可能[hello] world*在命令行中包含会做“有趣”的事情。-p $password另请参阅问题“忘记在 bash/POSIX shell 中引用变量的安全隐患”

    您在这里想要做的与我们通常想要避免的相反,即使用变量中的文件名通配模式调用文件名通配。

    如果您确实不能依靠提取目录的名称来保持稳定,那么更好的(如“更清洁”)解决方案可能是确保它是临时目录中唯一的东西,然后只使用*移动它就位(可能在此过程中更改其名称,以便您确定它的名称)。

    这比简单地删除变量周围的引号要好,因为文件名通配模式可能会匹配您期望的单个名称之外的其他名称,具体取决于目录中可用的其他内容。

    这是我对您上一个问题的回答的变体:

    #!/bin/sh -ex
    
    destdir="/var/www/html/phpmyadmin"
    
    tmpdir=$(mktemp -d)
    trap 'rm -rf "$tmpdir"' EXIT    # remove temporary directory on termination
    
    wget -O "$tmpdir/archive.zip" \
        "https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.zip"
    
    cd "$tmpdir" && {
        unzip archive.zip
        rm -f archive.zip
    
        # The only thing in the current (temporary) directory now is the
        # directory with the unpacked zip file.
    
        mkdir -p "$destdir"
        mv ./* "$destdir"/phpmyAdmin
    } 
    

    以上内容可归纳为五个步骤:

    1. 创建一个空目录(并将当前工作目录更改为它)。
    2. 获取存档。
    3. 提取存档。
    4. 删除存档。
    5. 现在在其他空目录中更改单独文件夹的名称。
    • 6
  2. Michael Homer
    2018-02-15T00:10:40+08:002018-02-15T00:10:40+08:00

    我怎样才能保持变量扩展双引号,但仍然使用带通配符的提取值?

    你不能1,你不想;没有它们,您的命令可以很好地工作(我很确定在这个问题的早期删除的变体之一中也指出了这一点)。

    $ mkdir phpMyAdmin-4.7.7-all-languages
    $ pma=[pP][hH][pP][mM][yY][aA][dD][mM][iI][nN]
    $ echo $pma
    [pP][hH][pP][mM][yY][aA][dD][mM][iI][nN]
    $ echo $pma*/
    phpMyAdmin-4.7.7-all-languages/
    $ mv $pma*/ phpmyadmin
    $ ls
    phpmyadmin
    

    引用变量的目的是确保不会发生shell globbing和字段拆分。这次您实际上希望发生这种情况,因此引用会适得其反。

    值得了解为什么存在这些准则;它们不是一揽子规则,如果它们不适合您,那么您可能会处于不适用的情况。在不理解它们的情况下努力“毫无例外地遵循最佳实践”是完全错误的。


    除此之外,这个:

    我还了解到,不能在双引号变量扩展之后立即使用 shell glob(通配符(*))。

    不是真的。

    $ tmp=php
    $ echo "$tmp"*
    phpmyadmin
    

    1你可以使用eval,但这完全没有意义,我不会再继续下去了。

    • 0

相关问题

  • 使用 POSIX 工具正确处理带有 BOM 的 Unicode 文件

  • 为什么正则表达式与 sed 命令的输入不匹配 [重复]

  • 两个点 (..) 或两个破折号 (--) 作为文件和目录名称中的分隔符

  • 使用特殊字符转换密码以与期望脚本一起使用

  • 更少:使用 AND 的多个过滤条件

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve