【问题标题】:How to check availability of each directoriy (directory tree) in a file path. Unix/Bash如何检查文件路径中每个目录(目录树)的可用性。 Unix/Bash
【发布时间】:2019-12-17 08:38:02
【问题描述】:

给定一个带有路径的文本文件(每一行都有一个新路径)。 需要从路径创建目录。这很容易像mkdir -p is/isapp/ip/ipapp 一样完成。然后chgrp group1 is/isapp/ip/ipapp。但问题是访问仅更改最终的ipapp 目录。并且您需要更改所有新创建目录的访问权限,而不更改在 mkdir -p 命令之前已经存在的目录的访问权限。因此,您需要检查哪些目录已经存在并仅更改新创建的目录的权限。下面我尝试从文件中拆分路径并逐渐增加它,直到搜索没有找到目录的那一刻。然后chgrp -R 带有未找到目录的路径。下面是我的代码草图。如果有任何帮助,我将不胜感激。

#!/bin/bash
FILE=$1 /(file with paths(in each line new path))
while read LINE; do
IFS='/' read -ra my_array <<< "$my_string"
  if ! [ -d "${my_array[0]}" ]; then
  mkdir -p "${my_array[0]}"
  else -d "${my_array[0]}"/"${my_array[@]}"
done
fi

【问题讨论】:

  • 嗯,就是这样,但你在哪里使用FILEelse -d 是怎么回事?最好通过shellcheck.net 运行此程序并修复它突出显示的所有错误,然后更新您的 Q。如果您包含一些应处理的示例数据,它将避免播放“20 个问题”。您想要包含错误检查吗?包含错误然后数据。man mkdir 并阅读有关-m 选项的信息。它可能会有所帮助。最后,您似乎需要第二个内部循环来处理/path/to/dir 的每个段(如果我正确理解您的 Q ). 祝你好运!
  • $my_string 来自哪里?最好阅读while read rec ; do .... cmds ; done &lt; inputFile。请更新您的 Q 并尽可能避免在 cmets 中回复。祝你好运。
  • 请用组发布示例输入文件和示例输出目录/文件布局。您可以使用basenamedirname“从文件中拆分路径”。

标签: arrays bash shell unix increment


【解决方案1】:

这样的事情会起作用:(基本上对于每个目录级别都尝试 cd up,如果您无法创建具有适当权限的目录)。

#!/bin/bash
MODE=u+rw
ROOT=$(pwd)
while read PATH; do
        IFS='/' read -r -a dirs <<< "${PATH}"
        for dir in "${dirs[@]}"; do
             [ -d "${dir}" ] || mkdir "${dir}" -m ${MODE} || exit 1
             cd "${dir}"
        done
        cd "${ROOT}"
done

注意:这是从标准输入读取的(因此您必须将文件通过管道传输到脚本中),或者在 done 之后添加 &lt; ${FILE} 以手动输入)。 "${dir}""${dirs[@]}" 周围的引号是必需的,以防文件名中有任何空白字符。

exit 1 会在mkdir 失败时保存您(假设有一个文件与您要创建的目录同名)。

【讨论】:

  • 这段代码运行良好!谢谢你的帮助!但我需要更改组的权限(现在这是通过 'chgrp group1 is/isapp/ip/ipapp' 完成的)。例如带有路径的文件的路径 - 'is/isapp/al/prog1'。但是我在 Linux 中已经有了这个目录 - is/isapp。我应该为他们创建 al 和 prog1 目录并设置他们的组权限,比如 chgrp group1 并且不要触及任何已经存在的目录的权限和组权限。
  • 我尝试替换 '[ -d "${dir}" ] || mkdir "${dir}" -m ${MODE} ||用一个新的退出 1' - '[ -d "${dir}" ] || mkdir "${dir}" || sudo chgrp group1 "${dir}" ||退出 1' 但它不起作用。我是 bash 新手,所以我不完全理解如何实现它。对于这个问题,我非常感谢您的帮助。
  • || 是短路或运算符。也就是说,如果你有a || b,它将首先运行a。如果a 返回成功,它不会打扰运行b。所以在你的情况下,你做了[ -d "${dir} ] || mkdir ${dir} || sudo chgrp group1 "${dir}" || exit 1。请注意,该目录不存在(因此您的第一个条件失败)。然后它会尝试第二个条件,即 mkdir,它通过了,因此它不会打扰下一个 || 运算符的 rhs。你可能想这样做:[ -d "${dir}" ] || ( mkdir "${dir} &amp;&amp; sudo chgrp group1 "${dir}" ) || exit 1
  • 我很抱歉,我在描述文件中存储的路径格式有误(不像 {is/isapp/al},而是像这样 {/home/username/ is/isapp/al} (完整路径)。现在,当我运行脚本时,会创建一个目录,如 {/home/username/is/isapp/al} 但我不需要 {home} 和 {username} 目录。我尝试在不同的地方添加 {~/},但没有帮助。也许您可以帮助解决这个问题?对于再次打扰您,我深表歉意
  • 您可以简单地删除 bash 数组的每个元素前面的前缀:dir=( "${dir[@]##/home/username/} ) 请参阅 here 了解可以在 bash 中完成的字符串操作。
猜你喜欢
  • 1970-01-01
  • 2018-04-01
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多