我有一个bash脚本,用于搜索unrar文件的密码。我想连接结果并在脚本结束时通知执行结果,但我不知道为什么final_result var输出“INIT-END”。
为什么不在search_pass_and_unrar函数中连接?
#!/bin/bash
# Url for finding rar files
url_hdd="/media/HDD"
final_result="INIT-"
unrar_files(){
filebase=`dirname "$1"`
url_rar="$1"
url_for_pass=""
# Search files for password
find "$filebase" -name '*CONTR*.txt' | while read LINE; do
# Convert Windows line ending
$(sed -i 's/^M//g' "$LINE")
# Get url where we can find file password
url_for_pass=$(cat "$LINE" | grep -Eo '(http|https)://[^?"]+')
search_pass_and_unrar "$url_for_pass" "$url_rar" "$filebase"
done
}
search_pass_and_unrar(){
final_url="$1"
pass=$(curl -s -S -L "$final_url" | grep 'name="txt_password"' | grep -oP 'value="\K[^"]+')
if [[ -z "$pass" ]]
then
final_result+="Error, password not found"
return
fi
result_unrar=$(unrar e "${2}" "${3}" -p"${pass}")
final_result+="Result: ${result_unrar}"
}
# Find rar files and call unrar_files function
find "$url_hdd" -type f -name "*.rar" | while read LINE; do
unrar_files "$LINE"
done
final_result+="END"
echo "$final_result" # "INIT-END"
非常感谢,最诚挚的问候。
答案 0 :(得分:1)
问题出在这里:
# Find rar files and call unrar_files function
find "$url_hdd" -type f -name "*.rar" | while read LINE; do
unrar_files "$LINE"
done
由于此处使用的管道,您的脚本正在分支另一个子shell并在子shell中调用unrar_files
。由于此子shell创建,对final_result
所做的所有更改在当前shell中都不可见。
您可以使用进程替换来解决此问题:
# Find rar files and call unrar_files function
while IFS= read -d '' -r LINE; do
unrar_files "$LINE"
done < <(find "$url_hdd" -type f -name '*.rar' -print0)
请注意使用-print0
以确保我们也可以处理具有特殊字符的文件。
同样在unrar_files
内你需要这样:
while IFS= read -d '' -r LINE; do
# Convert Windows line ending
$(sed -i 's/^M//g' "$LINE")
# Get url where we can find file password
url_for_pass=$(cat "$LINE" | grep -Eo '(http|https)://[^?"]+')
search_pass_and_unrar "$url_for_pass" "$url_rar" "$filebase"
done < <(find "$filebase" -name '*CONTR*.txt' -print0)