최근 내 호스팅 공급자가 public_html
내가 모르는 사이에 내 디렉터리 이름을 변경했기 때문에 이 변수 선언은 더 이상 유효하지 않습니다.www
web_application_root="${HOME}/public_html"
public_html"
해당 호스팅 환경에서 반드시 필요한 것은 아니지만 유사한 향후 상황을 위해 Bash에게 XOR 기반 변수를 생성하도록 지시하고 싶습니다 www
.
가능하다면 어떻게 가능합니까?
답변1
내 생각엔 네가 더 잘할 수 없을 것 같아
web_application_root="${HOME}/public_html"
if [ ! -d "$web_application_root" ] ; then
web_application_root="${HOME}/www"
fi
다양한 형태로. 예를 들어
for loc in "${HOME}/public_html" "${HOME}/www" ; do
web_application_root=$loc
[ -d "$loc" ] && break
done
본질적으로 존재하는 첫 번째 디렉토리를 찾아서 사용하십시오.
답변2
나는 여기 스레드의 질문에 대답하려고 노력할 것입니다.
*.txt
와일드카드는 일치하는 파일 경로 목록과 같이 와일드카드 패턴을 확장한 것입니다 .
files=(~/*.txt)
~
이름이 배열의 개별 요소로 끝나는 숨김되지 않은 파일 목록을 할당합니다 (glob이 어떤 파일과도 일치하지 않을 때 동작은 쉘마다 다릅니다)..txt
$files
XOR(A, B)
A
or 가 참 이면 참 B
이지만 둘 다 참은 아니므로 다음과 같습니다.AND(OR(A, B), NOT(AND(A, B)))
나는 XOR
glob/와일드카드 연산자가 있는 쉘을 모르지만 여러 쉘 에는 하나 와 OR
가 있습니다 NOT
. ).AND
AND(X, Y)
NOT(OR(NOT(X), NOT(Y)))
XOR
AND-NOT
AND
AND-NOT(X, NOT(Y))
이 공식을 결합하면 다음과 같은 결과를 얻습니다.
XOR(A, B) == NOT(OR(NOT(OR(A, B)), NOT(NOT(NOT(OR(NOT(A), NOT(B)))))))
이를 다음과 같이 단순화할 수 있습니다(이중 부정 제거).
XOR(A, B) == NOT(OR(NOT(OR(A, B)), NOT(OR(NOT(A), NOT(B)))))
ksh
또는 bash -o extglob
(또는 ) 전역 변수 로 변환되면 zsh -o kshglob
다음과 같습니다.
!(!(A|B)|!(!(A)|!(B)))
또는 zsh -o extendedglob
글로브를 사용하십시오:
^(^(A|B)|^(^A|^B))
또는 다음을 사용하십시오 AND-NOT
.
XOR(A, B) == AND-NOT(OR(A, B), NOT(NOT(AND-NOT(A, NOT(B)))))
다음과 같이 단순화할 수 있습니다.
XOR(A, B) == AND-NOT(OR(A, B), AND-NOT(A, NOT(B)))
일단 zsh -o extendedglob
glob으로 변환되면:
(A|B)~(A~^B)
foo*
예를 들어, 일치 하지만 둘 다 일치하지 않는 파일을 찾으려면 *.txt
다음을 수행합니다.
그리고 ksh
또는 bash -o extglob
(또는 zsh -o kshglob
):
files=(!(!(foo*|*.txt)|!(!(foo*)|!(*.txt))))
또는 다음을 사용하여 zsh -o extendedglob
:
files=(^(^(foo*|*.txt)|^(^foo*|^*.txt)))
또는:
files=((foo*|*.txt)~(foo*~^*.txt))
POSIX 쉘에는 이진(비트 단위) XOR 산술 연산자가 있습니다. 그대로 $(( 1 ^ 2 ))
로 확장됩니다 .3
XOR(0b01, 0b10)
xor
따라서 두 셸 코드의 평가 중 하나만 true를 반환하는 경우 true를 반환하는 함수를 다음과 같이 정의할 수 있습니다 .
xor() {
eval "$1"; s1=$((!$?))
eval "$2"; s2=$((!$?))
[ "$((s1 ^ s2))" -ne 0 ]
}
match() {
case $1 in
($2) true;;
(*) false;;
esac
}
for file in *; do
if
xor 'match "$file" "foo*"' \
'match "$file" "*.txt"' &&
then
printf '%s\n' "$file"
fi
done