我想要一个 bash shell 脚本(适用于我的 Debian 12 系统),它接受多个路径作为参数,然后检查是否可以在每个路径中成功创建文件。然后应将结果放入 json 格式。
要运行的命令应该是:
./checkavailable.sh /the/first/path /the/second/path
(其中可以给出任意数量的输入路径,但至少有一个)并且我希望输出采用以下格式:
[
{ "is_available": 0, "path": "/the/first/path/" },
{ "is_available": 1, "path": "/the/second/path/" }
]
目前,我已使用以下脚本成功实现此目的:
#!/bin/bash
# Check if first path is available
if touch $1/checkalivefile ; then
avail_path1=1
rm $1/checkalivefile
else
avail_path1=0
fi
# Check if second path is available
if touch $2/checkalivefile ; then
avail_path2=1
$2/checkalivefile
else
avail_path2=0
fi
echo "["
printf " { \"is_available\": "$avail_path1", \"path\": \"$1\" } "
printf ",\n"
printf " { \"is_available\": "$avail_path2", \"path\": \"$2\" } "
echo
echo "]"
但它显然有点原始,并且硬编码为仅适用于 x2 参数,并且不能扩展到其他参数。
我现在可以尝试添加一个循环。但是,我遇到了这个脚本,它似乎做了类似的事情(在这种情况下获取磁盘使用情况),但使用 awk 而不是循环:
#!/bin/bash
echo "["
du -s -B1 "$@" | awk '{if (NR!=1) {printf ",\n"};printf " { \"dir_size_bytes\": "$1", \"path\": \""$2"\" }";}'
echo
echo "]"
有人能演示一下如何使用“awk”来处理我的情况吗?我对 bash 脚本很陌生,所以希望能学到一些东西。
JSON 是一种糟糕的格式选择,因为当使用 UTF-8 编码时(现在通常需要这样做,而许多工具不支持非 UTF-8 编码的 JSON),它的字符串不能包含任意文件路径(非 NUL 字节的任意序列)。
但是如果你愿意像 Linux 上的许多工具一样生成非 UTF-8 编码的 JSON
lsfd
(但这些工具无法jq
处理),你可以执行以下操作:尽管你也可以将其制作成
perl
脚本:请注意,它不会尝试在其中创建文件,因为这可能会造成破坏(并且至少会更新这些目录的修改时间),而是使用启发式方法(检查路径是否标识可搜索(
-x
)和w
可写入的d
目录)。只是
->indent->space_after->indent_length(2)
为了获得jq
-style 的漂亮格式。您可以将其删除以获取紧凑的 JSON(就像使用 一样jq -c
)。例如,如果您确实想要一个/数字而不是/布尔值,请
!!
用int
或替换。0+
is_available
0
1
false
true
您的脚本和
df
脚本测试不同的东西。一个测试“我可以写入此目录吗”,另一个测试“此磁盘上是否有空间”。假设您想要“我可以写”测试,您的原始脚本很接近,但您需要稍微重构并循环输入。
像这样的简单循环的最大问题是删除最后的“,”因此我们将其放在一行中,然后删除循环的最后一行。JSON 不关心逗号在哪里,只要它在那里就行。
可能
touch
还需要将 stderr 扔掉。此版本尚未经过全面测试...
许多 Bourne 衍生的 shell 具有用于检查此类事物的原语,在具有与和运算符类似的实用程序
touch
的 shell 下不需要这样做:test
-d
-w
使用来自的关联数组
bash4+
。help test
检查权限。就像其他发布的答案所建议的那样。而不是touch
和rm
它可能类似于:json
,也可以使用 shell处理/处理数据结构。由于 UNIX 路径很可能包含双引号和其他字符,直接插入这些字符会破坏 JSON 文件,因此让 JSON 处理器处理该任务会更安全。
脚本也可以大大简化。
我会做这样的事情:
如果保证路径不包含无效的 UTF-8 序列;否则,正如 Stéphane Chazelas 指出的那样,需要某种编码才能使用 JSON 正确表示路径;请参阅Stéphane Chazelas 的回答,了解处理包含无效 UTF-8 序列的路径的方法。
对于每个参数
$p
,它将测试参数是否是一个可写且可搜索的目录,因此$?
将包含0
目录是否同时可写且可搜索 /1
目录是否同时可写且可搜索;is_available
然后,它将提供一个值为 的命名参数和一个值为 的$?
命名参数,它将输出一个包含数据的(格式良好的)JSON 对象;path
$p
jq
最后,它将把对象流输入
jq -s
到数组中。请注意,
is_available
应该将其表示为布尔值,否则无论解析 JSON 什么,可能都必须测试数字相等性而不是真实性:我不会使用 touch,而是测试路径是否可写
[[ -w "$p" ]]
。如果要专门测试目录是否可写,则使用[[ -d "$p" && -w "$p" ]]
。此外,我建议使用jo来处理任何 json 对象的创建。它让创建过程变得非常简单