고급 Bash 스 크 립 트 프로 그래 밍 가이드 (3): 변수 와 매개 변수 에 대한 소개

11679 단어 shell
고급 Bash 스 크 립 트 프로 그래 밍 가이드 (3): 변수 와 매개 변수 에 대한 소개
견지했어
변수 교체
변수의 이름 은 변수 가 값 을 저장 하 는 곳 입 니 다. 변 수 를 참조 하 는 값 을 변수 교체 라 고 합 니 다. "$"이 기 호 는 마치 표지 와 같 습 니 다.
변수의 이름과 변수의 값 을 자세히 구별 합 니 다. 만약 variable 가 변수의 이름 이 라면 $variable 는 이 변수의 값, 즉 이 변수 에 포 함 된 데 이 터 를 참조 합 니 다.
root@ubuntu:~# variable=12
root@ubuntu:~# echo variable
variable
root@ubuntu:~# echo $variable
12
변수 가 $접두사 가 없 을 때 변 수 는 다음 과 같은 몇 가지 상황 이 존재 할 수 있 습 니 다.
1. 변수 가 설명 되 거나 할당 되 거나,
2. 변 수 는 unset,
3. 변수 가 exporte 되 고,
4. 변 수 는 특수 한 상황 에 처 하고 변 수 는 신 호 를 대표 한다.
변수 할당 은 = (예 를 들 어 var 1 = 27) 을 사용 할 수 있 고 read 명령 이나 순환 헤더 에서 할당 할 수 있 습 니 다 (for var 2 in 1, 2, 3).
한 쌍 의 작은 따옴표 ("") 로 묶 인 변 수 를 바 꾸 는 것 은 막 히 지 않 습 니 다. 따라서 작은 따옴표 가 일부 인용 이 라 고도 부 르 고 약 한 인용 이 라 고도 부 릅 니 다. 그러나 작은 따옴표 를 사용 하면 (') 변 수 를 바 꾸 는 것 이 금지 되 고 변 수 는 글자 의 뜻 으로 만 해석 되 며 변 수 를 바 꾸 지 않 습 니 다. 그래서 작은 따옴표 가 전체 인용 이 라 고도 부 르 고 때로는 전체 인용 이 라 고도 부 릅 니 다."강 인용".
$variable 는 사실상 ${variable} 의 약자 형식 입 니 다. 일부 컨 텍스트 에서 $variable 는 오 류 를 일 으 킬 수 있 습 니 다. 이 럴 때 ${variable} 을 사용 해 야 합 니 다.
다음은 하나의 예 로 설명 한다.
#!/bin/bash
# 变量赋值和替换
a=375 #这里没有$说明是声明并且赋值了
hello=$a #$a表示使用变量a的值,把这个值赋值给hello这个变量
#-------------------------------------------------------------------------
# 强烈注意, 在赋值的的时候, 等号前后一定不要有空格.
# 如果出现空格会怎么样?
# "VARIABLE =value"
# 脚本将尝试运行一个"VARIABLE"的命令, 带着一个"=value"参数.
# "VARIABLE= value"
# 脚本将尝试运行一个"value"的命令, 并且带着一个被赋值成""的环境变量"VARIABLE". 
#-------------------------------------------------------------------------
echo hello #没有$这里打印hello变量的名字
echo $hello #打印hello变量的值
echo ${hello} #同样是打印hello变量的值

echo "$hello" 
echo "${hello}"

hello="A B  C   D" #重新赋值
echo $hello   # A B C D 引用一个变量将保留其中的空白, 当然, 如果是变量替换就不会保留了.
echo "$hello" # A B  C   D

echo '$hello'
hello=
echo "\$hello (null value) = $hello"

V3=23
var1=21  var2=22  var3=$V3
echo "var1=$var1   var2=$var2   var3=$var3"

numbers="one two three"
other_numbers="1 2 3"
echo "numbers = $numbers"
echo "other_numbers = $other_numbers"

mixed_bag=2\ ---\ Whatever
echo "$mixed_bag"
echo "uninitialized_variable = $uninitialized_variable"
uninitialized_variable=
echo "uninitialized_variable = $uninitialized_variable"
uninitialized_variable=23
unset uninitialized_variable
echo "uninitialized_variable = $uninitialized_variable"
exit 0
이 스 크 립 트 의 실행 결 과 를 보십시오.
root@ubuntu:~/resource/study/shell_study# ./value-test 
hello
375
375
375
375
A B C D
A B  C   D
$hello
$hello (null value) = 
var1=21   var2=22   var3=23
numbers = one two three
other_numbers = 1 2 3
2 --- Whatever
uninitialized_variable = 
uninitialized_variable = 
uninitialized_variable = 

초기 화 되 지 않 은 변 수 는 "null"값 입 니 다. - 할당 되 지 않 은 값 입 니 다. (그러나 대표 값 이 0 이 아 닙 니 다!) 변 수 를 할당 하기 전에 이 변 수 를 사용 하면 문제 가 발생 합 니 다.
그러나 산술 작업 을 수행 할 때 초기 화 되 지 않 은 변 수 를 사용 할 수 있 습 니 다.
root@ubuntu:~/resource/study/shell_study# echo "$data"

root@ubuntu:~/resource/study/shell_study# let "data +=5"
root@ubuntu:~/resource/study/shell_study# echo "$data"
5

결론: 초기 화 되 지 않 은 변 수 는 값 이 없 지만 산술 작업 을 할 때 초기 화 되 지 않 은 변 수 는 0 으로 보 입 니 다. 이것 은 문서 화 되 지 않 은 행위 입 니 다. 
할당 작업 (앞 뒤 공백 이 있어 서 는 안 됩 니 다)
= 과 - eq 는 모두 조건 테스트 작업 을 할 수 있 기 때문에 이곳 의 할당 작업 과 혼동 하지 마 십시오.
메모: = 조건 테스트 작업 도 할 수 있 고 할당 작업 도 할 수 있 습 니 다. 이것 은 구체 적 인 문맥 에 따라 정 해 야 합 니 다.
간단 한 할당 작업 예:
#!/bin/bash

# 赋值
a=879
echo "The value of \"a\" is $a."
# 使用'let'赋值
let a=16+5
echo "The value of \"a\" is now $a."
# 在'for'循环中(事实上, 这是一种伪赋值):
echo -n "Values of \"a\" in the loop are: " #这里加上-n表示忽略string最后的换行操作,否则会换行
for a in 7 8 9 11
do
	echo -n "$a "
done
echo
# 使用'read'命令进行赋值(这也是一种赋值的类型):
echo -n "Enter \"a\": "
read a #读取输入的值
echo "The value of \"a\" is now $a."
exit 0
실험 결과:
root@ubuntu:~/resource/study/shell_study# ./value-test1 
The value of "a" is 879.
The value of "a" is now 21.
Values of "a" in the loop are: 7 8 9 11 
Enter "a": 121212
The value of "a" is now 121212.
조금 더 복잡 한 예 를 보 자.
#!/bin/bash
a=23              # 简单的赋值
echo $a
b=$a
echo $b
# 现在让我们来点小变化(命令替换).
a=`echo Hello!`   # 把'echo'命令的结果传给变量'a'
echo $a
a=`ls -l`         # 把'ls -l'的结果赋值给'a'
echo $a           # 然而, 如果没有引号的话将会删除ls结果中多余的tab和换行符.
echo
echo "$a"         # 如果加上引号的话, 那么就会保留ls结果中的空白符.
exit 0
실험 결 과 를 살 펴 보 자.
root@ubuntu:~/resource/study/shell_study# chmod 777 value-test2 
root@ubuntu:~/resource/study/shell_study# ./value-test2
23
23
Hello!
total 48 -rwxrwxrwx 1 root root 663 2013-04-22 03:34 clear_log -rw-r--r-- 1 root root 354 2013-04-22 03:15 data-file -rwxrwxrwx 1 root root 404 2013-04-22 05:05 for_test -rwxrwxrwx 1 root root 345 2013-04-22 03:16 include_file -rwxrwxrwx 1 root root 831 2013-04-22 04:08 para_sub -rwxrwxrwx 1 root root 253 2013-04-22 00:35 show_self -rwxrwxrwx 1 root root 256 2013-04-22 04:41 test1 -rwxrwxrwx 1 root root 204 2013-04-22 04:50 test2 -rw-r--r-- 1 root root 59 2013-04-22 04:50 test-context -rwxrwxrwx 1 root root 1221 2013-04-23 22:33 value-test -rwxrwxrwx 1 root root 415 2013-04-23 22:51 value-test1 -rwxrwxrwx 1 root root 439 2013-04-23 22:57 value-test2

total 48
-rwxrwxrwx 1 root root  663 2013-04-22 03:34 clear_log
-rw-r--r-- 1 root root  354 2013-04-22 03:15 data-file
-rwxrwxrwx 1 root root  404 2013-04-22 05:05 for_test
-rwxrwxrwx 1 root root  345 2013-04-22 03:16 include_file
-rwxrwxrwx 1 root root  831 2013-04-22 04:08 para_sub
-rwxrwxrwx 1 root root  253 2013-04-22 00:35 show_self
-rwxrwxrwx 1 root root  256 2013-04-22 04:41 test1
-rwxrwxrwx 1 root root  204 2013-04-22 04:50 test2
-rw-r--r-- 1 root root   59 2013-04-22 04:50 test-context
-rwxrwxrwx 1 root root 1221 2013-04-23 22:33 value-test
-rwxrwxrwx 1 root root  415 2013-04-23 22:51 value-test1
-rwxrwxrwx 1 root root  439 2013-04-23 22:57 value-test2

Bash 변 수 는 유형 을 구분 하지 않 습 니 다.
다른 프로그램 언어 와 마찬가지 로 Bash 는 변수 에 대해 '유형' 을 구분 하지 않 습 니 다. 본질 적 으로 Bash 변 수 는 모두 문자열 입 니 다. 그러나 구체 적 인 문맥 에 의존 하여 Bash 도 비교 작업 과 정수 작업 을 허용 합 니 다. 그 중에서 관건 적 인 요 소 는 변수의 값 이 숫자 만 있 는 지 여부 입 니 다.
다음은 실례 를 보 겠 습 니 다.
#!/bin/bash
a=2334                   # 整型.
let "a += 1"
echo "a = $a "           # a = 2335

 b=${a/23/BB}            # 将"23"替换成"BB".
echo "b = $b"            # b = BB35
declare -i b              # 即使使用declare命令也不会对此有任何帮助.
echo "b = $b"            # b = BB35

let "b += 1"             # BB35 + 1 =
echo "b = $b"            # b = 1

c=BB34
echo "c = $c"            # c = BB34
d=${c/BB/23}             # 将"BB"替换成"23".
                         # 这使得变量$d变为一个整形.
echo "d = $d"            # d = 2334
let "d += 1"             # 2334 + 1 =
echo "d = $d"            # d = 2335
# null变量会如何呢?
e=""
echo "e = $e"            # e =
let "e += 1"             # 算术操作允许一个null变量?
echo "e = $e"            # e = 1
# 如果没有声明变量会怎样?
echo "f = $f"            # f =
let "f += 1"             # 算术操作能通过么?
echo "f = $f"            # f = 1
# 所以说Bash中的变量都是不区分类型的.
exit 0
그 가 집행 결 과 를 보 자.
root@ubuntu:~/resource/study/shell_study# ./int-char 
a = 2335 
b = BB35
b = BB35
b = 1
c = BB34
d = 2334
d = 2335
e = 
e = 1
f = 
f = 1

변 수 를 구분 하지 않 는 유형 은 행운 이자 비참 한 일 입 니 다. 스 크 립 트 를 작성 할 때 더욱 유연 하 게 (하지만 당신 을 어 지 럽 히 기 에 충분 합 니 다!) 코드 를 쉽게 작성 할 수 있 습 니 다. 그러나 오류 가 발생 하기 쉬 우 며 나 쁜 프로 그래 밍 습관 을 기 를 수 있 습 니 다.
이렇게 되면 프로그래머 는 스 크 립 트 의 변수 유형 을 구분 하 는 책임 을 집 니 다. Bash 는 변수 유형 을 구분 하지 않 습 니 다.
특수 변수 형식
국부 변수
이 변 수 는 코드 블록 이나 함수 에서 만 볼 수 있 습 니 다.
환경 변수
이러한 변 수 는 사용자 인터페이스 와 셸 의 행동 에 영향 을 줄 것 이다.
일반적인 상황 에서 모든 프로 세 스 는 자신의 '환경' 을 가지 고 있 습 니 다. 이 환경 은 하나의 변수 로 구성 되 어 있 습 니 다. 이 변수 들 에는 프로 세 스 가 인용 해 야 할 정보 가 저장 되 어 있 습 니 다. 이러한 상황 에서 셸 은 일반적인 프로 세 스 와 다 를 바 없습니다.
셸 이 시 작 될 때마다 환경 변수 에 맞 는 셸 변 수 를 만 듭 니 다. 새로운 환경 변 수 를 업데이트 하거나 추가 하면 이 셸 은 자신의 환경 을 즉시 업데이트 합 니 다.(번역자 주: 정확히 말 하면 후계 생 성 된 하위 프로 세 스 가 셸 의 새로운 환경 변 수 를 계승 해 야 합 니 다. 이미 실행 중인 하위 프로 세 스 는 새로운 환경 변 수 를 얻 지 못 합 니 다).
환경 변수 에 분 배 된 공간 은 유한 합 니 다. 환경 변 수 를 너무 많이 만 들 거나 환경 변수 에 너무 많은 공간 을 분배 하면 오류 가 발생 할 수 있 습 니 다.
스 크 립 트 가 환경 변 수 를 설정 하려 면 이 변 수 를 export 해 야 합 니 다."나 오 면 스 크 립 트 로 컬 환경 에 알려 야 합 니 다. 이것 은 export 명령 의 기능 입 니 다. 하나의 스 크 립 트 는 이 스 크 립 트 가 만 든 하위 프로 세 스 로 변 수 를 export 할 수 있 습 니 다. 즉, 이 스 크 립 트 가 만 든 명령 과 프로 세 스에 만 작용 할 수 있 습 니 다. 만약 스 크 립 트 가 명령 행 에서 호출 된다 면 이 스 크 립 트 의 export 변 수 는 명령 행 환경 에 영향 을 줄 수 없습니다.하위 프로 세 스 는 부모 프로 세 스 환경 에 영향 을 줄 수 없 는 export 변 수 를 사용 할 수 없습니다.
위치 매개 변수
명령 행 에서 스 크 립 트 로 전 달 된 인자: $0, $1, $2, $3.. $0 은 스 크 립 트 파일 자체 의 이름 입 니 다. $1 은 첫 번 째 인자 이 고, $2 는 두 번 째 인자 이 며, $3 은 세 번 째 인자 이 고, 그 다음은 네 번 째 인자 입 니 다. $9. 그 후의 위치 변 수 는 괄호 로 묶 어야 합 니 다. 예 를 들 어 ${10}, ${11}, ${12}. 비교적 특수 한 변수 $* 와 $@ 은 모든 위치 변 수 를 표시 합 니 다.
인 스 턴 스 하나 보 겠 습 니 다.
#!/bin/bash
# 作为用例, 调用这个脚本至少需要10个参数, 比如:
# ./scriptname 1 2 3 4 5 6 7 8 9 10
MINPARAMS=10
echo "The name of this script is \"$0\"."
echo "The name of this script is \"`basename $0`\"."

if [ -n "$1" ]              # 测试变量被引用.
then
	echo "Parameter #1 is $1"  # 需要引用才能够转义"#"
fi 

if [ -n "$2" ]
then
	echo "Parameter #2 is $2"
fi 

if [ -n "$3" ]
then
	echo "Parameter #3 is $3"
fi 

if [ -n "${10}" ]  # 大于$9的参数必须用{}括起来.
then
	echo "Parameter #10 is ${10}"
fi 
echo "-----------------------------------"
echo "All the command-line parameters are: "$*""
if [ $# -lt "$MINPARAMS" ]
then
	echo "This script needs at least $MINPARAMS command-line arguments!"
fi  
exit 0
실험 결 과 를 살 펴 보 자.
root@ubuntu:~/resource/study/shell_study# ./args 1 2 3 
The name of this script is "./args".
The name of this script is "args".
Parameter #1 is 1
Parameter #2 is 2
Parameter #3 is 3
-----------------------------------
All the command-line parameters are: 1 2 3
This script needs at least 10 command-line arguments!
root@ubuntu:~/resource/study/shell_study# ./args 1 2 3 4 5 6 7 8 9 10 11
The name of this script is "./args".
The name of this script is "args".
Parameter #1 is 1
Parameter #2 is 2
Parameter #3 is 3
Parameter #10 is 10
-----------------------------------
All the command-line parameters are: 1 2 3 4 5 6 7 8 9 10 11
{} 표기 법 은 명령 행 에서 스 크 립 트 로 전달 되 는 마지막 위치 매개 변 수 를 추출 하 는 간단 한 방법 을 제공 합 니 다.
일부 스 크 립 트 는 서로 다른 호출 이름 을 사용 하여 다른 행동 을 보일 수 있 습 니 다. 이러한 목적 을 달성 하려 면 스 크 립 트 에서 $0 을 검사 해 야 합 니 다. 스 크 립 트 는 하나의 실제 파일 이름 만 있 을 수 있 기 때문에 여러 개의 이름 을 만 들 려 면 기호 링크 를 사용 해 야 합 니 다. 
shift 명령 의 사용 인 스 턴 스 를 보십시오:
#!/bin/bash
# 使用'shift'来逐步存取所有的位置参数. 给脚本命个名, 比如shft,然后给脚本传递一些位置参数, 比如: ./shft a b c def 23 skidoo

until [ -z "$1" ]  # 直到所有的位置参数都被存取完...
do
	echo -n "$1 "
	shift
done
echo
exit 0
실험 결과 보기:
root@ubuntu:~/resource/study/shell_study# ./shift d df lsjf sldjf
d df lsjf sldjf 

먼저 여기까지, O (∩ ∩) O ~
내 칼럼 주소:http://blog.csdn.net/column/details/shell-daily-study.html
계속

좋은 웹페이지 즐겨찾기