나는 나를 당황하게 만드는 다음 bash 기능을 가지고 있습니다. zenity 상자에 다음을 입력하면 ...
직원 ID = 2 카테고리 ID = 3
나는 다음을 얻습니다: 2 3
만약에...
직원 ID = 카테고리 ID = 3
두 번째 zenity 창이 열린 후 2를 입력하면 다음과 같은 결과가 나타납니다. 2 3
그런데 내가 들어갈 때
직원 ID = 2 카테고리 ID =
추가 Zenity 창이 열리지 않고 다음과 같은 메시지가 표시됩니다. 2
내가 정말로 끝내고 싶은 것은 테스트가 실행된 후 2,3입니다.
여기에 무엇이 잘못되었는지 아는 사람이 있나요?
#!/bin/bash
num(){
emp=$(echo "$1" | awk -F, -v OFS=, '{print $1 "," $2}')
IFS=, read -ra array1 <<<"$emp"
p=$(for i in "${array1[@]}"
do
if [[ "${i}" =~ ^[0-9]+$ ]]; then
out="${i}"
elif
[[ "${i}" = NULL ]]; then
out="${i}"
else local var2
until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do
var2="$(zenity --forms --title="table salaries_wages" --text "Add a number" --separator="," \
--add-entry="WARNING! You either forgot to enter or didn't enter a number. Please enter a valid number: ")"
done
out="${var2}"
fi
echo "$out"
done)
echo "$p"
}
input="$(zenity --forms --title="table salaries_wages" --text="Add a new salaries_wages entry" --separator="," \
--add-entry="ENTER employeeid: " \
--add-entry="ENTER categoryid: ")"
num "$input"
답변1
여기서 무슨 문제가 있나요?
작동 방식에 대한 가정은 실제 작동 read
방식과 다릅니다 . read
Bash에서 다음 코드를 실행하세요.
how_many () { IFS=, read -ra array1 <<<"$1"; echo "${#array1[@]}"; }
how_many "2,3"
how_many ",3"
how_many "2,"
당신은 얻을 것이다 2
, 2
, 1
. 마지막 숫자가 눈에 띕니다. 이는 후행 구분 기호( ,
이 경우) read
가 종결자처럼 처리된다는 것을 의미합니다. 빈 필드가 배열로 읽히지 않고 배열이 너무 짧은 요소로 끝나게 됩니다. 코드에서 이런 일이 발생하면 for i in "${array1[@]}"
첫 번째 필드에 대해서만 루프가 실행됩니다.
해결책은 다음을 도입하는 것일 수 있습니다.추가의 ,
의도적으로 후행 터미네이터로 사용되었습니다. 그런 다음 read
세 번째 필드는 읽지 않지만 항상 두 개의 필드를 읽습니다(두 번째 필드가 비어 있는 경우에도). 추가 항목을 추가할 때 차이점을 확인하세요 ,
.
how_many () { IFS=, read -ra array1 <<<"$1,"; echo "${#array1[@]}"; }
how_many "2,3"
how_many ",3"
how_many "2,"
how_many ","
출력은 2
매번입니다.
<<<"$emp,"
이 방법 으로 코드를 수정하려면 <<<"$emp"
.
else
코드를 수정하면 블록이 두 번 이상 실행될 때(즉, 두 필드가 처음에 유효하지 않은 경우) 오작동합니다 . 왜냐하면 당신은var2
변수 재사용다시.
나는 당신이 이것을 피하곤 했다고 생각 local var2
하지만 블록이나 루프의 단일 반복이 local
아닌 함수에서 변수를 로컬로 만듭니다 . 동일한 함수 인스턴스에서 재사용하고 있습니다 .else
for
var2
num
함수를 한 번 호출합니다. 내부는 var2
항상 동일하며 var2
, 이 함수 호출을 통해 외부 local
와 구별될 뿐입니다 . 함수 외부에서 var2
사용했다면 함수 안의 함수는 구별됩니다. 두 번 이상 var2
호출하면 num
각 호출마다 고유한 var2
. 둘 다 발생하지 않습니다. 함수를 한 번 호출하고 변수를 재사용합니다.거기. 두 필드가 유효하지 않은 경우 변수는 첫 번째 필드에 사용된 다음재사용두 번째 필드의 경우.
그러나 코드를 다시 작성하여 validate
루프 내에서 일부 함수(예: )가 호출되는 경우:
for i in "${array1[@]}"; do validate "$i"; …
함수 local var2
에서 사용하면 각 함수 호출에서 구별됩니다. 이것이 도움이 될 수 있는 방법입니다. 각 루프에서 새로 호출되고 해당 지역 변수는 동일한 이름을 가진 다른 변수에 연결되지 않고 새로 초기화됩니다. 그러나 여전히 지역 변수를 재사용할 수 있습니다.validate
var2
local
validate
내부에무언가를 중단시키는 방식으로 함수를 사용합니다(현재 함수 var2
에서 재사용하는 방법과 유사 num
).
위의 내용을 작성한 후이미 연결된 답변.
Note는 p=$(stuff); echo "$p"
와 거의 동일하며 echo "$(stuff)"
, 거의 항상 just 여야 합니다 stuff
. 읽어주세요이 답변자세히 설명되어 있는 곳입니다 var=$(stuff); echo "$var"
.