![在子 shell 中变量赋值 echo $VAR 是一个好方法吗? (嵌套 bash 函数)](https://linux22.com/image/184586/%E5%9C%A8%E5%AD%90%20shell%20%E4%B8%AD%E5%8F%98%E9%87%8F%E8%B5%8B%E5%80%BC%20echo%20%24VAR%20%E6%98%AF%E4%B8%80%E4%B8%AA%E5%A5%BD%E6%96%B9%E6%B3%95%E5%90%97%EF%BC%9F%20%EF%BC%88%E5%B5%8C%E5%A5%97%20bash%20%E5%87%BD%E6%95%B0%EF%BC%89.png)
我不是 BASH 程序员,每当我必须创建脚本时,这对我来说都是一次彩票,所以如果我的脚本看起来太冗余或由新手编写,我深表歉意。
作为前言,我有许多在 Windows 计算机上拍摄的屏幕快照,其中捕获了两个显示器。我将它们组织在子文件夹中,我想采用通用方法来裁剪其中的图像。顺便说一句,因为我不喜欢 Windows 生成的文件名,即带有空格和括号,所以我想删除这些字符。
以上只是我可能必须对子文件夹中的文件应用操作的众多情况之一。我按照对文件执行的操作来组织脚本。
现在重点是:在编写脚本时,我希望它是通用的,因此我尝试让函数的行为像其他脚本语言一样,如果不是绝对必要的话,尽量不使用全局变量。
现在重点是:由于我最终必须将字符串分配给变量,所以我被迫在子 shell 中使用“echo -n”,我读到了关于在子 shell 中使用 echo 将由空格或其他特殊字符组成的字符串分配给变量的相反评论。
我一一测试了下面的三个功能,它们起作用了。这意味着当需要时我会在函数本身中强制值。
一旦我将它们嵌套在第三个中,我唯一知道的是,如果我不使用这种在子 shell 中回显变量并捕获输出的技术,它永远不会起作用:除了一个变量,在底部。
trim_weird_char () {
# set +x
local _bn="$(basename "$1")"
# echo "[twc bn] $_bn"
local _dn="$(dirname "$1")"
# echo "[twc dn] $_dn"
local _fn="$(echo -n $_bn | tr -d ' ' | tr -d '(' | tr -d ') ')"
# echo "[twc fn] $_fn"
local _ifn="$(echo -n "${_dn}"/"${_bn}")"
local _dfn="$(echo -n "${_dn}"/"${_fn}")"
mv "$_ifn" "$_dfn"
echo "$_dfn"
# set -x
}
crop_img() {
# set +x
#$1 = image
#$2 = resize
#$3 = string to add in the output filename before the extension
local _img="$(echo -n "$1")"; # we want the file name and hence we remove the extension by NOT being GREEDY with the removal
local _fn="$(echo -n "${_img%.*}")"
local _ext="$(echo -n "${_img##*.}")"; # we want the extension and hence we remove what comes before by being GREEDY with the removal
local _dfn="$(echo -n "${_fn}${3}.${_ext}")"
convert "$_img" -crop "$2" "$_dfn"
echo "$(echo -n "$_dfn")"
}
crop_smartbe () {
# set -x
# ls -la | awk '{print $5}'
echo -n "Trimming name for $1..."
local _img="$(trim_weird_char "$1")"
echo "done: $_img"
echo -n "Cropping $_img to... "
local _s="$(ls -la "$_img" | awk '{print $5}')"
local _dfn="$(echo -n $(crop_img "$_img" "1080x1920+0+0" "_cropped"))"
local _s_img=$(ls -la "$_dfn" | awk '{print $5}')
echo "$_dnf done: size from $_s to $_s_img"
}
我测试功能的文件名如下(我获取了上面的脚本)
gadger@brunas:/brunas/expenses/2020/Demandes de reimbursement/Demandes$ crop_smartbe Full/1261597\ -\ Frais\ Internet\ -\ 1er\ sémestre/Screenshot\ \(142\).png
Trimming name for Full/1261597 - Frais Internet - 1er sémestre/Screenshot (142).png...done: Full/1261597 - Frais Internet - 1er sémestre/Screenshot142.png
Cropping Full/1261597 - Frais Internet - 1er sémestre/Screenshot142.png to... done: size from 292631 to 100694
为此(在crop_smartbe中)
local _dfn="$(echo -n $(crop_img "$_img" "1080x1920+0+0" "_cropped"))"
...
echo "$_dnf done: size from $_s to $_s_img"
即使我使用了 echo -n 技术,$_dnf 仍然没有正确分配。
理所当然地认为删除 echo 函数会破坏脚本,我应该更喜欢 printf 吗?或者我应该以不需要使用 echo 的不同方式重写脚本?万一怎么办?
谢谢亚历克斯