이것은 내 스크립트입니다.
if [[ "$(echo "$2" | sed 's/.two//g')" == "load" ]] && [[ "$1" == "Decrypt" ]] || [[ "$(echo "$2" | sed 's/.two//g')" == "load" ]] && [[ "$1" == "Encrypt" ]]
then
key=aNXlye1tGbd0uP
else
if [ -z "$key" ]
then
key="$2"
fi
fi
두 번째 매개변수를 찾아 전위를 제거한 .two
다음 와 비교하고, load
그렇다면 로 load
설정해야 합니다 . 그러나 이것은 작동하지 않습니다. 실행해 보면 이런 느낌이에요.key
aNXlye1tGbd0uP
pskey Decrypt load (some string)
이것은 다음의 출력입니다 bash -x
.
++ echo load
++ sed s/.two//g
+ [[ load == \l\o\a\d ]]
+ [[ Decrypt == \D\e\c\r\y\p\t ]]
+ [[ Decrypt == \E\n\c\r\y\p\t ]]
+ '[' -z '' ']'
+ key=load
그러나 뒤에 오는 것을 제거하면 [[ "$1" == "Decrypt" ]]
작동합니다. 그 라인에 문제가 있나요?
답변1
내가 올바르게 이해했다면 다음과 같은 것을 찾고 있습니다.
if [[ "$(echo "$2" | sed 's/.two//g')" == "load" && "$1" == "Decrypt" ]] ||
[[ "$(echo "$2" | sed 's/.two//g')" == "load" && "$1" == "Encrypt" ]]
then
...
fi
다음과 같이 모든 것을 단순화할 수도 있습니다.
if [[ "$(echo "$2" | sed 's/.two//g')" == "load" && "$1" =~ (De|En)crypt ]]; then ...
답변2
terdon의 진술은 "이것은 '단순함'과는 거리가 멀습니다 if
." ~처럼존 쿠겔만(John Kugelman)은 다음과 같이 지적했다., 동일한 우선순위를 가지며 왼쪽에서 오른쪽으로 처리됩니다
&&
.||
BinaryZebra가 이 아이디어를 제안했습니다.부울 표현식을 계단식 if
명령문으로 변환합니다. 나는 "단순화"하려고 노력한다
A && B인 경우 || 그 다음에 결과=0 기타 결과=1 필리핀 제도
예
만약 그 다음에 B라면 그 다음에 만약 D ← 그 다음에 결과=0 기타 결과=1 필리핀 제도 기타 만약 C 그 다음에 만약 D 그 다음에 결과=0 기타 결과=1 필리핀 제도 기타 결과=1 필리핀 제도 필리핀 제도 기타 만약 C 그 다음에 만약 D 그 다음에 결과=0 기타 결과=1 필리핀 제도 기타 결과=1 필리핀 제도 필리핀 제도
아주 멀리간단하게 시작하세요. 위에서 알 수 있듯이 작동하지 않는 이유는 (표시된 줄에서) A와 B가 모두 true인 경우 D( [[ "$1" == "Encrypt" ]]
)를 계속 테스트하기 때문입니다.
BinaryZebra가 보여주지만 언급하지는 않는 것처럼,할 수 있는예를 들어 sh/bash 스크립트에 수학적 표기법을 사용하면 됩니다.
if (A && B) || 그 다음에 ︙
또는 약간 단순화된 코드 버전에서는
만약에([["$2"=="로드"]] && [["$1"=="해독"]]) || ([["$2"=="로드 중"]] && [["$1"=="암호화됨"]]) 그 다음에 ︙
그 특징은 괄호 안의 코드가 서브쉘에서 실행된다는 것입니다. 이것이 문제라면 중괄호를 대신 사용할 수 있습니다.
만약에{[["$2"=="로드"]] && [["$1"=="해독"]]; || {[["$2"=="로드 중"]] && [["$1"=="암호화됨"]]; 그 다음에 ︙
앞에 하나 (선택적으로 공백으로 구분) ;
가 있어야 하며 앞 , 뒤, 뒤에 공백이 있어야 합니다 .}
{
}
물론 다른 답변에서 제안한 기술을 사용해야 합니다.단순화하다귀하의 테스트입니다.아니요동일한 테스트를 두 번 수행합니다
$2
.
관련된:파이프 및 리디렉션과 분리, 조인 등에 대한 바인딩 우선 순위는 무엇입니까?그리고"if"가 불필요한 경우는 언제입니까?
답변3
코드에서:
if [[ "$(echo "$2" | sed 's/.two//g')" == "load" ]] &&
[[ "$1" == "Decrypt" ]] ||
[[ "$(echo "$2" | sed 's/.two//g')" == "load" ]] &&
[[ "$1" == "Encrypt" ]]
sed 호출은 다음과 같이 단순화될 수 있습니다. ${2%?two}
if 대체는 변수 끝에 있습니다 $2
. 점(.)은 패턴의 물음표(?)에 해당하는 sed의 "모든 문자"를 의미한다는 점을 이해하시기 바랍니다(@terdon에게 감사드립니다). 모든 항목을 교체해야 하는 경우 다음을 .two
사용해야 합니다 "${2//?two}"
. 그런 다음 다음과 같은 더 짧은 버전을 얻습니다.
if [[ "${2//?two}" == "load" ]] && [[ "$1" == "Decrypt" ]] ||
[[ "${2//?two}" == "load" ]] && [[ "$1" == "Encrypt" ]]
이게 뭐 하는 거야 if A && B || C && D
?
A가 참인 경우(로드 = 로드) B가 실행됩니다. B가 true(Decrypt = Decrypt)인 경우
다음 구문(C)을 건너뛰고 D(Decrypt = Encrypt)를 실행합니다. 결과(실행된 마지막 명령)는 값입니다. 그럼 실행해...||
false
else
나는 당신이 if ( A && B ) || ( C && D )
, as 가 와 A
동일 C
하고 와 정확히 같다는 것을 의미한다고 생각합니다 if ( A && B ) || ( A && D )
. 이는 단순화될 수 있습니다(사용하여재산을 분배하다) 도착하다
if A && ( B || D )
:
if [[ "${2//?two}" == "load" ]] &&
( [[ "$1" == "Decrypt" ]] || [[ "$1" == "Encrypt" ]] );
then
key=aNXlye1tGbd0uP
else
if [ -z "$key" ]
then key="$2"
fi
fi
"$key"에 대한 테스트는 -z
간단한 확장으로 축소될 수 있습니다: key="${key:-$2}"
그리고 아마도 다음과 같이 더 읽기 쉬울 것입니다(IMO).
if A; then
if B || D; then
번역하면 이렇습니다.
if [[ "${2//?two}" == "load" ]]
then if [[ "$1" == "Decrypt" ]] || [[ "$1" == "Encrypt" ]]
then key=aNXlye1tGbd0u
else key="${key:-$2}"
fi
else key="${key:-$2}"
fi
또는 @terdon의 아이디어를 사용하여 다음과 같이 작성할 수 있습니다.
if [[ "${2//?two}" == "load" ]] &&
[[ "$1" =~ (De|En)crypt ]]
then key=aNXlye1tGbd0u
else key="${key:-$2}"
fi
이것도 동일합니다.
if [[ ( "${2//?two}" == "load" ) &&
( "$1" =~ (De|En)crypt )
]]
then key=aNXlye1tGbd0u
else key="${key:-$2}"
fi
괄호는 꼭 필요한 것은 아니지만 [[
테스트 내부에서 공백(탭, 공백, 줄 바꿈) 및 괄호를 추가하여 테스트에 구조를 제공할 수 있다는 아이디어를 강화하기 위해 추가되었습니다. 이것은 테스트에서 다르게 작동했습니다 [
.
답변4
첫 번째:
[[ $1:$2 =~ ^(En|De)crypt:(.two)*load(.two)*$ ]] && echo conditions met
그러나 if
부울 논리는 반대입니다.
#sed #En=$1 #De=$1
true && false || true # passes your logic
true && true || NA # passes your logic
false && NA || false # fails your logic
false && NA || true # fails your logic
두 번째 것은 &&
요인이 아니기 때문에 여기서는 생략됩니다. 그 결과는 항상 첫 번째 것과 동일합니다. 이 논리 사슬에서 그것은 쓸모없는 것입니다.
이는 그다지 효과적이지 않습니다. 실패한 사례로 인해 귀하의 진술이 깨집니다. 첫 번째 테스트가 거짓인 경우에는 (De|En)crypt 테스트 대신 OR 반환을 수행합니다. 사실 첫 번째는 쇼트 때문에 발생하지도 않습니다.짐반품. 따라서 먼저 OR을 수행하고 실제로 테스트해야 할 때까지 비용이 많이 드는 명령 대체를 지연하여 단락을 활용해야 합니다.
#En=$1 #De=$1 #sed
false || false && NA
false || true && false
false || true && true
true || NA && false
true || NA && true
이 모든 것이 논리를 통과합니다. 처음 두 문이 모두 거짓이면 명령 대체가 시도되지 않습니다.
이는 case
및 다음 을 사용하여 이식 가능합니다 expr
.
case ${2%oad*}:${1%crypt} in
(:${key:=$2}*|*ad*|*:"$1") ;;
(*l:De|*l:En) expr " $2" : \
" \(\(.two\)*\(load\)*\)*$" &&
key=aNXlye1tGbd0uP
esac >/dev/null
그리고 if
:
if [ Encrypt = "$1" -o Decrypt = "$1" ] &&
expr " $2" : " \(.two\)*load\(.two\)*$"
then key=$newkey
else key=${key:-$2}
fi >/dev/null
그냥 expr
및 &&||
, if
그것은 당신에게 별로 도움이 되지 않기 때문에:
expr > /dev/null \
"${#1} ${1%crypt} $2" :\
"7 \(\(De\)*\(En\)*\) ""\
\(.two\)*load\(.two\)*$" &&
key=$newkey || key=${key:-$2}
아마도 다음과 같은 것들이 있을 것입니다 grep
:
grep -xqE '(En|De)crypt:(.two)*load(.two)*' \
<<VAR && key=$newkey || key=${key:-$2}
${1##*:*}:$2
VAR