У меня проблемы с получением переменной "${Error[*]}"
, которая является обычным индексированным массивом, чтобы он оставался установленным с момента объявления до его проверки.Мне кажется, что суб-оболочка должна быть запущена, чтобы объявление не прилипало.Я не думал, что вложенные оболочки открывались при использовании фигурных скобок { stuff...; }
.Я хочу знать, как получить мою переменную, Error
, чтобы придерживаться в случае, если я пытаюсь записать.Вот пример моего сценария:
TestFunction () {
unset Error
local archive="$1" extlist="$2" && local ext="${archive##*.}"
shopt -s nocasematch
local -i run=0
while [[ "$run" == 0 || -n "${Error[run]}" ]]; do
(( run++ ))
local IFS=$'\n\r\t '
if [[ ! "${Error[*]}" =~ 'cpio' && "$ext" =~ ^(pax|cpio|cpgz|igz|ipa|cab)$ && -n "$(which 'cpio')" ]]; then
## Try to cpio the archive. Since cpio cannot handle '.cab' archive, I want to declare an Error ##
{ cpio -ti --quiet <"$archive" 2>'/dev/null' || local -a Error[run]='cpio'; } | grep -Ei '$extlist'
elif [[ ! "${Error[*]}" =~ 'zipinfo' && "$ext" =~ ^(zip|[jw]ar|ipa|cab)$ && -n "$(which 'unzip')" ]]; then
## If cpio fails, then try zipinfo, or unzip on the next run through the loop... ##
if which 'zipinfo' &>'/dev/null'; then
{ zipinfo -1 "$archive" 2>'/dev/null' || local -a Error[run]='zipinfo'; } | grep -Ei "$scanlist"
elif which 'unzip' &>'/dev/null'; then
{ unzip -lqq "$archive" 2>'/dev/null' || local -a Error[run]='unzip'; } | gsed -re '/^ +[0-9]+/!d;s|^ +[0-9]+ +[0-9-]+ [0-9:]+ +||' | grep -Ei "$exlist"
fi
## many more elifs... ##
fi
done
shopt -u nocasematch
return 0
}
Archives='\.(gnutar|7-zip|lharc|toast|7zip|boz|bzi?p2?|cpgz|cpio|gtar|g?z(ip)?|lzma(86)?|t[bg]z2?|ar[cgjk]|bz[2a]?|cb[7rz]|cdr|deb|[dt]lz|dmg|exe|fbz|fgz|gz[aip]|igz|img|iso|lh[az]|lz[hmswx]?|mgz|mpv|mpz|pax|piz|pka|[jrtwx]ar|rpm|s?7-?z|sitx?|m?pkg|sfx|nz|xz)$'
IFS=$'\n'
declare -a List=($(TestFunction '/Users/aesthir/Programming/│My Projects│/Swipe Master/Test Folder/SDKSetup.cab' "$Archives"))
IFS=$' \t\n'
вывод:
〔xtrace〕 unset Error
〔xtrace〕 local 'archive=/Users/aesthir/Programming/│My Projects│/Swipe Master/Test Folder/SDKSetup.cab' 'extlist=\.(gnutar|7-zip|lharc|toast|7zip|boz|bzi?p2?|cpgz|cpio|gtar|g?z(ip)?|lzma(86)?|t[bg]z2?|ar[cgjk]|bz[2a]?|cb[7rz]|cdr|deb|[dt]lz|dmg|exe|fbz|fgz|gz[aip]|igz|img|iso|lh[az]|lz[hmswx]?|mgz|mpv|mpz|pax|piz|pka|[jrtwx]ar|rpm|s?7-?z|sitx?|m?pkg|sfx|nz|xz)$'
〔xtrace〕 local ext=cab
〔xtrace〕 shopt -s nocasematch
〔xtrace〕 local -i run=0
〔xtrace〕 [[ 0 == 0 ]]
〔xtrace〕 (( run++ ))
〔xtrace〕 local 'IFS=
'
〔xtrace〕 [[ ! '' =~ cpio ]]
〔xtrace〕 [[ cab =~ ^(pax|cpio|cpgz|igz|ipa|cab)$ ]]
〔xtrace〕 which cpio
〔xtrace〕 [[ -n /usr/bin/cpio ]]
〔xtrace〕 grep -Ei '$extlist'
〔xtrace〕 cpio -ti --quiet
〔xtrace〕 local -a 'Error[run]=cpio'
〔xtrace〕 [[ 1 == 0 ]]
〔xtrace〕 [[ -n '' ]] ## <—— Problem is here... when checking "${Error[run]}", it's unset ##
〔xtrace〕 shopt -u nocasematch
〔xtrace〕 return 0
Теперь, очевидно, я знаю, что
cpio
,
zipinfo
и
unzip
не могут обрабатывать cab-файлы ... Я специально добавил 'cab' в список расширений, чтобы вызвать ошибку.
Я хочуоставайтесь в TestFunction
и продолжайте циклы с различными архиваторами до успеха (список файлов сбрасывается, что с удовольствием сделает cabextract
в этом случае), не повторяя уже вышедший из строя архиватор.
Наконец, так как это работает нормально...
TestFunction () {
unset Error
local archive="$1" extlist="$2" && local ext="${archive##*.}"
local -i run=0
while [[ "$run" == 0 || -n "${Error[run]}" ]]; do
(( run++ ))
local IFS=$'\n\r\t '
if [[ ! "${Error[*]}" =~ 'cpio' && "$ext" =~ ^(pax|cpio|cpgz|igz|ipa|cab)$ && -n "$(which 'cpio')" ]]; then
cpio -ti --quiet <"$archive" 2>'/dev/null' || local -a Error[run]='cpio'
fi
done
shopt -u nocasematch
return 0
}
... Я должен предположить, что проблема в скобках, потому что я хочу получить результаты grep
сразу.Тем не менее, мне нужны эти скобки, потому что я не хочу, чтобы Error[run]
был установлен, если grep
не даст результатов, только если cpio
завершится неудачно.Я не хочу использовать grep за пределами TestFunction
по другим причинам (мне пришлось бы сделать полное переписывание).
Какое-нибудь быстрое решение этого вопроса без масштабной перезаписи?Может быть echo 'cpio'
для некоторого fd и read -u6
как-нибудь?
Я бы предпочел , а не , чтобы установить массив для списка файлов, а затем for loop | grep
через каждыйфайл, поскольку это действительно замедлило бы все.
Спасибо, ребята!
- Aesthir