【问题标题】:Bash script that checks for parts of current folderpath检查当前文件夹路径部分的 Bash 脚本
【发布时间】:2022-10-13 23:32:35
【问题描述】:

简洁明了:如何使用 bash 检查我当前所在文件夹的某些部分?

#!/usr/bin/sh
CURRENTFOLDER=$(pwd)
echo "${CURRENTFOLDER}"
CHECKFOLDER="/home/*/domains/*/public_html"
if [ $CURRENTFOLDER ! $CHECKFOLDER ]
then
    echo "Current folder is not /home/user/domains/domain.com/public_html"
    exit
fi

用户和域是可变的,我不需要知道它们进行检查,只需变量 CHECKFOLDER 中的 3 个预定义文件夹

【问题讨论】:

  • 如果您的脚本用于 bash,请在 shebang 中使用 bash

标签: bash


【解决方案1】:

这种方法有问题。
例如,在 bash 中,以下表达式的计算结果为 true

[[ /www/user/domains/local/public_html == /www/*/public_html ]] 

使用 bash 正则表达式更准确:

[[ /www/user/domains/local/public_html =~ ^/www/[^/]+/public_html$ ]]

所以你的代码会变成:

#!/bin/bash

current_folder=$PWD
check_folder='^/home/[^/]+/domains/[^/]+/public_html$'

if ! [[ $current_folder =~ $check_folder ]]
then
    echo "Current folder is not /home/user/domains/domain.com/public_html"
    exit
fi

顺便说一句,shebang 必须是 bash,而不是 sh。将变量大写有点危险。

【讨论】:

  • 如果任何路径包含符号链接,此方法可能会失败。
  • 我不确定符号链接与验证字符串是否与模式匹配有什么关系。你指的是$PWD吗?
  • 例如,运行cd /tmp; ln -s /home/auser/domains/adomain/public_html public_html; cd public_html 会更改为有效目录,但PWD 的值是/tmp/public_html
  • 我理解你的意思,但是如果脚本必须source ../lib/env.sh 会发生什么?只要它引用相同的inode,允许任何路径会不会很危险?
【解决方案2】:

试试这个(几乎)Shellcheck-clean 代码:

#! /usr/bin/sh

curr_phpath=''
for phpath in /home/*/domains/*/public_html/; do
    if [ "$phpath" -ef . ]; then
        curr_phpath=$phpath
        break
    fi
done

if [ -z "$curr_phpath" ]; then
    echo "Current folder is not /home/user/domains/domain.com/public_html" >&2
    exit 1
fi
  • 由于别名机制(例如符号链接、绑定挂载),通常很难通过文本比较来确定两个路径是否引用同一个文件或目录。有关更多信息,请参阅How to check if two paths are equal in Bash?。此解决方案使用更可靠的机制来确定当前目录是否为有效目录之一。
  • 由于 shebang 行引用 sh 而不是 bash,因此代码避免了 Bashisms。它已经过bashdash 的测试(可能是最常见的非Bash sh)。
  • 请参阅Correct Bash and shell script variable capitalization,了解代码为什么不使用 ALL_UPPERCASE 变量名的解释。
  • 如果被检查的.../public_html 路径与当前目录是同一目录,则[ "$phpath" -ef . ] 测试为真。 -ef 运算符不在 POSIX 中,因此不能保证 sh shell 支持它,Shellcheck(正确)会警告它。但是,bashdash 都支持它,sh 通常是其中之一(至少在 Linux 上)。

【讨论】:

  • 可能有点贵,但它是安全的,只要您在检查 +1 后cd "$curr_phpath"
【解决方案3】:

您可以通过更改目录而不是检查来保存步骤。

首先检查您的glob 仅匹配一个文件。

然后,cd 检查它是一个目录。

#! /bin/bash

IFS="$(printf '
	')"
files=( $(compgen -G '/home/*/domains/*/public_html') )
if [[ "${#files[@]}" != 1 ]]
then
    printf 'Multiple matches
' >&2
    exit 1
fi
if ! cd "${files[0]}" 
then
   printf 'Cannot chdir
'
   exit 1
fi

【讨论】:

  • 我不确定/home/*/domains/*/public_html 是否会扩展到仅一个目录
  • 是的,不知道结构是怎样的,但是如果有很多,那么有必要检查所需的目录是否在files
猜你喜欢
  • 2021-11-13
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 2015-08-12
相关资源
最近更新 更多