105.1 Bài 2
Chứng chỉ: |
LPIC-1 |
---|---|
Phiên bản: |
5.0 |
Chủ đề: |
105 Vỏ và Tệp lệnh Vỏ |
Mục tiêu: |
105.1 Tùy chỉnh và Sử dụng môi trường vỏ |
Bài: |
2 trên 3 |
Giới thiệu
Hãy coi một biến như một chiếc hộp tưởng tượng để tạm thời đặt một mẩu thông tin vào đó. Tương tự như với các tệp lệnh khởi tạo của nó, Bash sẽ phân loại các biến thành vỏ/cục bộ (những biến chỉ tồn tại trong giới hạn của vỏ mà chúng được tạo) hoặc môi trường/toàn cục (những biến được kế thừa bởi vỏ và/hoặc tiến trình con). Trên thực tế, trong bài học trước, chúng ta đã tìm hiểu về vỏ và các tệp lệnh cấu hình hoặc khởi tạo của chúng. Thật thuận tiện khi bây giờ chúng ta có thể chỉ ra rằng sức mạnh của các tệp khởi động này nằm ở chỗ chúng cho phép chúng ta sử dụng các biến — cũng như các bí danh và hàm — để tạo và tùy chỉnh môi trường vỏ mà chúng ta lựa chọn.
Biến: Gán và Tham chiếu
Một biến có thể được định nghĩa là một cái tên có chứa một giá trị.
Trong Bash, việc đặt giá trị cho tên được gọi là gán biến và đó là cách chúng ta tạo hoặc thiết lập biến. Mặt khác, quá trình truy cập giá trị chứa trong tên được gọi là tham chiếu biến.
Cú pháp để gán biến là:
<variable_name>=<variable_value>
Ví dụ:
$ distro=zorinos
Biến distro
ngang bằng với zorinos
, nghĩa là có một phần bộ nhớ giữ giá trị của zorinos
— với distro
trỏ tới nó.
Tuy nhiên, hãy lưu ý rằng khi gán một biến, ở hai bên của dấu bằng không được có bất kỳ một khoảng trắng nào:
$ distro =zorinos -bash: distro: command not found $ distro= zorinos -bash: zorinos: command not found
Do lỗi của chúng ta, Bash đã đọc distro
và zorinos
thành lệnh.
Để tham chiếu một biến (nghĩa là để kiểm tra giá trị của nó), chúng ta sẽ sử dụng lệnh echo
trước tên biến với dấu $
:
$ echo $distro zorinos
Tên của Biến
Khi chọn tên biến, có một số quy tắc nhất định mà chúng ta phải xem xét.
Tên của biến có thể chứa các chữ cái (a-z
,A-Z
), số (0-9
) và dấu gạch dưới (_
):
$ distro=zorinos $ echo $distro zorinos $ DISTRO=zorinos $ echo $DISTRO zorinos $ distro_1=zorinos $ echo $distro_1 zorinos $ _distro=zorinos $ echo $_distro zorinos
Tên của biến không được bắt đầu bằng một chữ số vì việc này có thể khiến Bash dễ nhầm lẫn:
$ 1distro=zorinos -bash: 1distro=zorinos: command not found
Tên của biến không được chứa dấu cách (thậm chí không được sử dụng cả dấu trích dẫn). Theo quy ước, dấu gạch dưới sẽ được sử dụng thay thế:
$ "my distro"=zorinos -bash: my: command not found $ my_distro=zorinos $ echo $my_distro zorinos
Giá trị của Biến
Liên quan đến việc tham chiếu hoặc giá trị của các biến, quan trọng nhất là ta phải xem xét một số quy tắc.
Các biến có thể chứa bất kỳ ký tự chữ và số nào (a-z
,A-Z
,0-9
) cũng như hầu hết những ký tự khác (?
,!
,*
,.
,/
, v.v. ):
$ distro=zorin12.4? $ echo $distro zorin12.4?
Các giá của trị biến phải được đặt trong dấu trích dẫn nếu chúng chứa các dấu cách đơn:
$ distro=zorin 12.4 -bash: 12.4: command not found $ distro="zorin 12.4" $ echo $distro zorin 12.4 $ distro='zorin 12.4' $ echo $distro zorin 12.4
Các giá trị của biến cũng phải được đặt trong dấu trích dẫn nếu chúng chứa các ký tự như các ký tự được sử dụng để chuyển hướng (<
,>
) hoặc ký hiệu dẫn ống (|
). Điều duy nhất mà lệnh sau thực hiện là tạo một tệp trống có tên zorin
:
$ distro=>zorin $ echo $distro $ ls zorin zorin
Tuy nhiên, khi chúng ta sử dụng dấu trích dẫn thì nó sẽ hoạt động như mong đợi:
$ distro=">zorin" $ echo $distro >zorin
Tuy nhiên, dấu trích dẫn đơn và dấu trích dẫn kép không phải lúc nào cũng có thể hoán đổi cho nhau. Tùy thuộc vào những gì chúng ta đang làm với một biến (gán hoặc tham chiếu), việc sử dụng biến này hay biến kia có ý nghĩa và sẽ mang lại kết quả khác nhau. Khi gán biến, dấu trích dẫn đơn sẽ đọc tất cả các ký tự của giá trị biến theo nghĩa đen, trong khi dấu trích dẫn kép sẽ cho phép thay thế biến:
$ lizard=uromastyx $ animal='My $lizard' $ echo $animal My $lizard $ animal="My $lizard" $ echo $animal My uromastyx
Mặt khác, khi tham chiếu một biến với giá trị có bao gồm một số khoảng trắng đứng đầu (hoặc bổ sung) — đôi khi được kết hợp với dấu hoa thị — chúng ta bắt buộc phải sử dụng dấu trích dẫn kép sau lệnh echo
để tránh phân tách trường và mở rộng tên đường dẫn:
$ lizard=" genus | uromastyx" $ echo $lizard genus | uromastyx $ echo "$lizard" genus | uromastyx
Nếu tham chiếu của biến có chứa dấu chấm than đóng thì đây phải là ký tự cuối cùng trong chuỗi (nếu không, Bash sẽ nghĩ rằng chúng ta đang đề cập đến một sự kiện trong quá khứ (history
):
$ distro=zorin.?/!os -bash: !os: event not found $ distro=zorin.?/! $ echo $distro zorin.?/!
Mọi dấu gạch chéo ngược đều phải được thoát bằng một dấu gạch chéo ngược khác. Ngoài ra, nếu dấu gạch chéo ngược là ký tự cuối cùng trong chuỗi và chúng ta không thoát nó thì Bash sẽ diễn giải rằng người dùng muốn ngắt dòng và sẽ cung cấp cho chúng ta một dòng mới:
$ distro=zorinos\ > $ distro=zorinos\\ $ echo $distro zorinos\
Trong hai phần tiếp theo, chúng ta sẽ tổng hợp những điểm khác biệt chính giữa biến cục bộ và môi trường.
Biến cục bộ - Biến Vỏ
Các biến cục bộ hay biến vỏ chỉ tồn tại trong vỏ mà chúng được tạo. Theo quy ước, các biến cục bộ sẽ được viết bằng chữ thường.
Để thực hiện một số thử nghiệm, hãy tạo một biến cục bộ. Như đã giải thích ở trên, chúng ta sẽ chọn một tên biến thích hợp và gán cho nó một giá trị thích hợp. Ví dụ:
$ reptile=tortoise
Bây giờ, chúng ta sẽ sử dụng lệnh echo
để tham chiếu biến và kiểm tra xem mọi thứ có diễn ra như mong đợi hay không:
$ echo $reptile tortoise
Trong một số trường hợp nhất định - chẳng hạn như khi viết tệp lệnh - tính bất biến có thể là một tính năng thú vị của các biến. Nếu muốn các biến của mình không thay đổi, chúng ta có thể tạo chúng ở chế độ readonly
(chỉ đọc):
$ readonly reptile=tortoise
Hoặc thay đổi sau khi chúng được tạo:
$ reptile=tortoise $ readonly reptile
Bây giờ, nếu chúng ta cố gắng thay đổi giá trị của reptile
, Bash sẽ từ chối:
$ reptile=lizard -bash: distro: readonly variable
Note
|
Để liệt kê tất cả các biến chỉ đọc trong phiên hiện tại, hãy nhập |
Một lệnh hữu ích khi xử lý các biến cục bộ là set
.
set
sẽ xuất ra tất cả các biến và hàm của vỏ hiện được gán. Vì nó có thể có rất nhiều dòng (hãy tự mình thử!) nên chúng ta nên sử dụng nó kết hợp với một trình đánh số chẳng hạn như less
:
$ set | less BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="4" [1]="4" [2]="12" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu") BASH_VERSION='4.4.12(1)-release' (...)
Biến reptile
có ở đó không?
$ set | grep reptile reptile=tortoise
Có!
Tuy nhiên, reptile
— là một biến cục bộ — sẽ không được kế thừa bởi bất kỳ tiến trình con nào được sinh ra từ vỏ hiện tại:
$ bash $ set | grep reptile $
Và tất nhiên, chúng ta cũng không thể lặp lại giá trị của nó:
$ echo $reptile $
Note
|
Bằng cách gõ lệnh |
Để hủy thiết lập bất kỳ biến nào (cục bộ hoặc toàn cục), chúng ta có thể sử dụng lệnh unset
:
$ echo $reptile tortoise $ unset reptile $ echo $reptile $
Note
|
|
Biến toàn cục - Biến môi trường
Các biến toàn cục hoặc biến môi trường tồn tại cho vỏ hiện tại cũng như cho tất cả các tiến trình tiếp theo được sinh ra từ nó. Theo quy ước, các biến môi trường sẽ được viết bằng chữ in hoa:
$ echo $SHELL /bin/bash
Chúng ta có thể truyền đệ quy giá trị của các biến này sang các biến khác và giá trị của biến sau sẽ mở rộng sang giá trị của biến trước:
$ my_shell=$SHELL $ echo $my_shell /bin/bash $ your_shell=$my_shell $ echo $your_shell /bin/bash $ our_shell=$your_shell $ echo $our_shell /bin/bash
Để biến một biến vỏ cục bộ trở thành một biến môi trường, ta phải sử dụng lệnh export
:
$ export reptile
Với export reptile
, chúng ta đã biến biến cục bộ của mình thành biến môi trường để các vỏ con có thể nhận ra và sử dụng nó:
$ bash $ echo $reptile tortoise
Tương tự, export
có thể được sử dụng để đặt và xuất một biến cùng một lúc:
$ export amphibian=frog
Bây giờ, chúng ta có thể mở một phiên Bash mới và tham chiếu thành công biến mới:
$ bash $ echo $amphibian frog
Note
|
Với |
Lệnh export
cũng sẽ cung cấp cho chúng ta một danh sách tất cả các biến môi trường hiện có khi được gõ riêng (hoặc với tùy chọn -p
):
$ export declare -x HOME="/home/user2" declare -x LANG="en_GB.UTF-8" declare -x LOGNAME="user2" (...) declare -x PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" declare -x PWD="/home/user2" declare -x SHELL="/bin/bash" declare -x SHLVL="1" declare -x SSH_CLIENT="192.168.1.10 49330 22" declare -x SSH_CONNECTION="192.168.1.10 49330 192.168.1.7 22" declare -x SSH_TTY="/dev/pts/0" declare -x TERM="xterm-256color" declare -x USER="user2" declare -x XDG_RUNTIME_DIR="/run/user/1001" declare -x XDG_SESSION_ID="8" declare -x reptile="tortoise"
Note
|
Lệnh |
Có hai lệnh nữa có thể được sử dụng để in danh sách tất cả các biến môi trường là env
và printenv
:
$ env SSH_CONNECTION=192.168.1.10 48678 192.168.1.7 22 LANG=en_GB.UTF-8 XDG_SESSION_ID=3 USER=user2 PWD=/home/user2 HOME=/home/user2 SSH_CLIENT=192.168.1.10 48678 22 SSH_TTY=/dev/pts/0 MAIL=/var/mail/user2 TERM=xterm-256color SHELL=/bin/bash SHLVL=1 LOGNAME=user2 XDG_RUNTIME_DIR=/run/user/1001 PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games _=/usr/bin/env
Ngoài việc là từ đồng nghĩa với env
, đôi khi chúng ta có thể sử dụng printenv
theo cách tương tự khi ta sử dụng lệnh echo
để kiểm tra giá trị của một biến:
$ echo $PWD /home/user2 $ printenv PWD /home/user2
Tuy nhiên, hãy lưu ý rằng với printenv
, tên của biến sẽ không có $
đứng trước.
Note
|
|
Chạy Chương trình trong một Môi trường đã được sửa đổi
env
có thể được sử dụng để sửa đổi môi trường vỏ tại thời điểm thực thi chương trình.
Để bắt đầu một phiên vỏ mới với một môi trường trống nhất có thể — xóa sạch hầu hết các biến (cũng như các hàm và bí danh) — chúng ta sẽ sử dụng env
với tùy chọn -i
:
$ env -i bash
Hầu hết các biến môi trường của chúng ta đã biến mất:
$ echo $USER $
Và chỉ còn lại một số ít:
$ env LS_COLORS= PWD=/home/user2 SHLVL=1 _=/usr/bin/printenv
Chúng ta cũng có thể sử dụng env
để đặt một biến cụ thể cho một chương trình cụ thể.
Trong bài học trước, khi thảo luận về vỏ không đăng nhập không tương tác, chúng ta đã thấy cách các tệp lệnh không đọc bất kỳ tệp khởi động tiêu chuẩn nào mà thay vào đó, chúng sẽ tìm giá trị của biến BASH_ENV
và sử dụng nó làm tệp khởi động nếu nó tồn tại.
Hãy cùng minh hoạ quá trình này:
-
Chúng ta sẽ tạo tệp khởi động của riêng mình có tên là
.startup_script
với nội dung sau:CROCODILIAN=caiman
-
Chúng ta sẽ viết một tệp lệnh Bash có tên
test_env.sh
với nội dung sau:#!/bin/bash echo $CROCODILIAN
-
Chúng ta sẽ đặt bit thực thi cho tệp lệnh
test_env.sh
của mình:$ chmod +x test_env.sh
-
Cuối cùng, chúng ta sẽ sử dụng
env
để đặtBASH_ENV
thành.startup_script
chotest_env.sh
:$ env BASH_ENV=/home/user2/.startup_script ./test_env.sh caiman
Lệnh
env
là lệnh ngầm ngay cả khi chúng ta loại bỏ nó:$ BASH_ENV=/home/user2/.startup_script ./test_env.sh caiman
Note
|
Nếu không hiểu dòng |
Biến môi trường chung
Bây giờ là lúc xem lại một số biến môi trường phù hợp nhất được đặt trong tệp cấu hình Bash.
DISPLAY
-
Liên quan đến máy chủ X, giá trị của biến này thường được tạo thành từ ba phần tử:
-
Tên máy chủ (không có nó thì sẽ là
localhost
) nơi máy chủ X đang chạy. -
Dấu hai chấm làm dấu phân cách.
-
Một chữ số (thường là
0
và đề cập đến màn hình của máy tính).$ printenv DISPLAY :0
Giá trị trống cho biến này có nghĩa là máy chủ không có Hệ thống X Window. Một số bổ sung — như trong
my.xserver:0:1
— đề cập đến số màn hình (nếu có nhiều hơn một).
-
HISTCONTROL
-
Biến này kiểm soát những lệnh nào được lưu vào
HISTFILE
(xem bên dưới). Chúng có ba giá trị có thể có:ignorespace
-
Các lệnh bắt đầu bằng dấu cách sẽ không được lưu.
ignoredups
-
Một lệnh giống với lệnh trước đó sẽ không được lưu.
ignoreboth
-
Các lệnh thuộc bất kỳ loại nào trong hai loại trước sẽ không được lưu.
$ echo $HISTCONTROL ignoreboth
HISTSIZE
-
Biến này sẽ thiết lập số lượng lệnh được lưu trong bộ nhớ trong suốt phiên vỏ.
$ echo $HISTSIZE 1000
HISTFILESIZE
-
Biến này sẽ thiết lập số lượng lệnh được lưu trong
HISTFILE
cả khi bắt đầu và kết thúc phiên:$ echo $HISTFILESIZE 2000
HISTFILE
-
Tên của tệp lưu trữ tất cả các lệnh khi chúng được gõ. Theo mặc định, tệp này được đặt tại
~/.bash_history
:$ echo $HISTFILE /home/user2/.bash_history
NoteĐể xem nội dung của
HISTFILE
, chúng ta chỉ cần gõhistory
. Ngoài ra, chúng ta có thể chỉ định số lượng lệnh mình muốn xem bằng cách truyền một đối số (số lệnh gần đây nhất) chohistory
như tronghistory 3
. HOME
-
Biến này lưu trữ đường dẫn tuyệt đối của thư mục chính của người dùng hiện tại và nó sẽ được thiết lập khi người dùng đăng nhập.
Đoạn mã này từ
~/.profile
đã tự giải thích chính nó (lấy nguồn từ"$HOME/.bashrc"
nếu nó tồn tại):# include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi
NoteNếu không hiểu rõ câu lệnh
if
thì cũng đừng lo lắng. Hãy tham khảo các bài học về tệp lệnh vỏ.Hãy nhớ rằng
~
cũng tương đương với$HOME
:$ echo ~; echo $HOME /home/carol /home/carol
NoteCác lệnh có thể được nối với nhau bằng dấu chấm phẩy (
;
).Chúng ta cũng có thể chứng minh điều này bằng câu lệnh
if
:$ if [ ~ == "$HOME" ]; then echo "true"; else echo "false"; fi true
NoteHãy nhớ: Dấu bằng
=
được sử dụng để gán biến, còn==
được sử dụng để kiểm tra các giá trị tương đương. HOSTNAME
-
Biến này lưu trữ tên TCP/IP của máy chủ:
$ echo $HOSTNAME debian
HOSTTYPE
-
Biến này lưu trữ kiến trúc của bộ vi xử lý của máy chủ:
$ echo $HOSTTYPE x86_64
LANG
-
Biến này lưu trữ ngôn ngữ của hệ thống:
$ echo $LANG en_UK.UTF-8
LD_LIBRARY_PATH
-
Biến này bao gồm một tập hợp các thư mục được phân tách bằng dấu hai chấm nơi các thư viện chia sẻ được các chương trình cùng sử dụng:
$ echo $LD_LIBRARY_PATH /usr/local/lib
MAIL
-
Biến này lưu trữ tệp mà Bash tìm kiếm email:
$ echo $MAIL /var/mail/carol
Một giá trị chung khác cho biến này là
/var/spool/mail/$USER
. MAILCHECK
-
Biến này lưu trữ một giá trị số cho biết tần suất Bash kiểm tra email mới tính bằng giây:
$ echo $MAILCHECK 60
PATH
-
Biến môi trường này lưu trữ danh sách các thư mục nơi Bash sẽ tìm kiếm các tệp thực thi khi được yêu cầu chạy bất kỳ chương trình nào. Trong máy ví dụ của chúng ta, biến này được thiết lập thông qua tệp toàn hệ thống
/etc/profile
:if [ "`id -u`" -eq 0 ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" else PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" fi export PATH
Thông qua câu lệnh
if
, danh tính của người dùng sẽ được kiểm tra và — tùy thuộc vào kết quả kiểm tra (root
hoặc loại người dùng khác) — chúng ta sẽ nhận được mộtPATH
thuộcroot
hoặc mộtPATH
thuộc người dùng khác. Cuối cùng,PATH
được chọn sẽ được truyền lại bằngexport
.Hãy quan sát hai điều liên quan đến giá trị của
PATH
:-
Tên thư mục được viết bằng đường dẫn tuyệt đối.
-
Dấu hai chấm được dùng làm dấu phân cách.
Nếu muốn đưa thư mục
/usr/local/sbin
vàoPATH
cho người dùng thông thường, chúng ta sẽ sửa đổi dòng sao cho nó trông như dưới đây:(...) else PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/sbin" fi export PATH
Bây giờ, chúng ta có thể thấy giá trị của biến thay đổi như thế nào khi đăng nhập với tư cách người dùng thông thường:
# su - carol $ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/sbin
NoteChúng ta cũng có thể thêm
/usr/local/sbin
vàoPATH
của người dùng tại dòng lệnh bằng cách gõPATH=/usr/local/sbin:$PATH
hoặcPATH=$PATH:/usr/local /sbin
.PATH=/usr/local/sbin:$PATH
sẽ đặt/usr/local/sbin
làm thư mục đầu tiên được tìm kiếm cho các tệp thực thi.PATH=$PATH:/usr/local /sbin
sẽ làm cho nó trở thành thư mục cuối cùng.
-
PS1
-
Biến này lưu trữ giá trị của dấu nhắc lệnh Bash. Trong đoạn mã sau đây (cũng từ
/etc/profile
), câu lệnhif
sẽ kiểm tra danh tính của người dùng và cung cấp cho họ một lời nhắc rất riêng biệt tương ứng (#
choroot
hoặc$
cho người dùng thông thường):if [ "`id -u`" -eq 0 ]; then PS1='# ' else PS1='$ ' fi
Noteid
củaroot
là0
. Hãy đăng nhập với tư cáchroot
và tự mình kiểm tra nó bằngid -u
.Các biến nhắc lệnh khác bao gồm:
PS2
-
Thường được đặt thành
>
và được sử dụng làm dấu nhắc lệnh tiếp tục cho các lệnh nhiều dòng dài. PS3
-
Được sử dụng làm dấu nhắc lệnh cho lệnh
select
. PS4
-
Thường được đặt thành
+
và được sử dụng để gỡ lỗi.
SHELL
-
Biến này lưu trữ đường dẫn tuyệt đối của vỏ hiện tại:
$ echo $SHELL /bin/bash
USER
-
Biến này lưu trữ tên của người dùng hiện tại:
$ echo $USER carol
Bài tập Hướng dẫn
-
Hãy quan sát việc gán biến trong cột “Lệnh” và cho biết biến kết quả là “Cục bộ” hay “Toàn cục”:
Lệnh Cục bộ Toàn cục debian=mother
ubuntu=deb-based
mint=ubuntu-based; export mint
export suse=rpm-based
zorin=ubuntu-based
-
Hãy xem “Lệnh” và “Đầu ra” và giải thích ý nghĩa:
Lệnh Đầu ra Ý nghĩa echo $HISTCONTROL
ignoreboth
echo ~
/home/carol
echo $DISPLAY
reptilium:0:2
echo $MAILCHECK
60
echo $HISTFILE
/home/carol/.bash_history
-
Các biến đang được đặt không chính xác trong cột “Lệnh sai”. Hãy điền thông tin còn thiếu trong cột “Lệnh đúng” và “Tham chiếu biến” để có thể nhận được “Đầu ra dự kiến”:
Lệnh sai Lệnh đúng Tham chiếu biến Đầu ra dự kiến lizard =chameleon
chameleon
cool lizard=chameleon
chameleon
lizard=cha|me|leon
cha|me|leon
lizard=/** chameleon **/
/** chamelon **/
win_path=C:\path\to\dir\
C:\path\to\dir\
-
Hãy đọc mục đích và viết lệnh thích hợp:
Mục đích Lệnh Đặt ngôn ngữ của vỏ hiện tại thành UTF-8 tiếng Tây Ban Nha (
es_ES.UTF-8
).In tên của thư mục làm việc hiện tại.
Tham chiếu biến môi trường lưu trữ thông tin về các kết nối
ssh
.Đặt
PATH
để/home/carol/scripts
làm thư mục cuối cùng khi tìm kiếm các tệp thực thi.Đặt giá trị của
my_path
thànhPATH
.Đặt giá trị của
my_path
thành giá trị củaPATH
. -
Hãy tạo một biến cục bộ có tên
mammal
và gán cho nó giá trịgnu
: -
Bằng cách sử dụng thay thế biến, hãy tạo một biến cục bộ khác có tên
var_sub
với giá trị phù hợp để khi được tham chiếu quaecho $var_sub
, chúng ta sẽ thu được:The value of mammal is gnu
: -
Hãy biến
mammal
thành một biến môi trường: -
Hãy tìm nó bằng
set
vàgrep
: -
Hãy tìm nó bằng
env
vàgrep
: -
Bằng hai lệnh liên tiếp, hãy tạo một biến môi trường có tên
BIRD
và có giá trị làpenguin
: -
Bằng một lệnh duy nhất, hãy tạo một biến môi trường có tên
NEW_BIRD
và có giá trị làyellow-eyed penguin
: -
Giả sử bạn là
user2
, hãy tạo một thư mục có tên làbin
trong thư mục chính của bạn: -
Hãy nhập lệnh để thêm thư mục
~/bin
vàoPATH
của bạn để nó là thư mục đầu tiênbash
tìm các tệp nhị phân: -
Để đảm bảo giá trị của
PATH
không bị thay đổi trong các lần khởi động lại, bạn sẽ đặt đoạn mã nào — dưới dạng câu lệnhif
— vào~/.profile
?
Bài tập Mở rộng
-
let
: hơn cả một lệnh tính biểu thức số học:-
Hãy xem trang hướng dẫn hoặc thực hiện tìm kiếm trên web về
let
và ý nghĩa của nó khi đặt biến và tạo một biến cục bộ mới có tênmy_val
có giá trị là10
— là kết quả của 5 + 5: -
Bây giờ, hãy tạo một biến khác có tên
your_val
có giá trị là5
— là kết quả của việc chia giá trịmy_val
với 2:
-
-
Kết quả của một lệnh nằm trong một biến? Tất nhiên là điều này có thể xảy ra. Nó được gọi là thay thế lệnh. Hãy tìm hiểu và nghiên cứu hàm có tên
music_info
sau:music_info(){ latest_music=`ls -l1t ~/Music | head -n 6` echo -e "Your latest 5 music files:\n$latest_music" }
Kết quả của lệnh
ls -l1t ~/Music | head -n 6
sẽ trở thành giá trị của biếnlatest_music
. Sau đó, biếnlatest_music
sẽ được tham chiếu trong lệnhecho
(xuất ra tổng số byte bị chiếm bởi thư mụcMusic
và năm tệp nhạc mới nhất được lưu trữ trong thư mụcMusic
— mỗi tệp một dòng).Lựa chọn nào sau đây đồng nghĩa hợp lệ với
latest_music=`ls -l1t ~/Music | head -n 6`
Lựa chọn A:
latest_music=$(ls -l1t ~/Music| head -n 6)
Lựa chọn B:
latest_music="(ls -l1t ~/Music| head -n 6)"
Lựa chọn C:
latest_music=((ls -l1t ~/Music| head -n 6))
Tóm tắt
Trong bài học này, chúng ta đã học về:
-
Các biến là một phần rất quan trọng của môi trường vỏ vì chúng được sử dụng bởi chính vỏ cũng như các chương trình khác.
-
Cách gán và tham chiếu biến.
-
Sự khác biệt giữa các biến cục bộ và toàn cục (hoặc môi trường).
-
Cách tạo biến chỉ đọc.
-
Cách biến biến cục bộ thành biến môi trường bằng lệnh
export
. -
Cách liệt kê tất cả các biến môi trường.
-
Cách chạy chương trình trong môi trường đã sửa đổi.
-
Cách duy trì các biến với sự trợ giúp của các tệp lệnh khởi động.
-
Một số biến môi trường phổ biến:
DISPLAY
,HISTControl
,HISTSIZE
,HISTFILESIZE
,HISTFILE
,HOME
,HOSTNAME
,HOSTTYPE
,LANG
,LD_LIBRARY_PATH
,MAIL
,MAILCHECK
,PATH
,PS1
(và các biến nhắc nhở khác),SHELL
vàUSER
. -
Ý nghĩa của dấu ngã (
~
). -
Những khái niệm cơ bản về câu lệnh
if
.
Các lệnh được sử dụng trong bài học này:
echo
-
Tham chiếu một biến
l
-
Liệt kê nội dung thư mục.
readonly
-
Làm cho các biến trở nên bất biến. Liệt kê tất cả các biến chỉ đọc trong phiên hiện tại.
set
-
Liệt kê tất cả các biến và hàm trong phiên hiện tại.
grep
-
In các dòng khớp với mẫu.
bash
-
Khởi chạy một vỏ mới.
unset
-
Bỏ thiết lập các biến.
export
-
Biến biến cục bộ thành biến môi trường. Liệt kê các biến môi trường.
env
-
Liệt kê các biến môi trường. Chạy một chương trình trong một môi trường được sửa đổi.
printenv
-
Liệt kê các biến môi trường. Tham chiếu một biến
chmod
-
Thay đổi các bit chế độ của một tệp (ví dụ như làm cho nó có thể thực thi được).
history
-
Liệt kê các lệnh trước đó.
su
-
Thay đổi ID người dùng hoặc trở thành siêu người dùng.
id
-
In ID người dùng.
Đáp án Bài tập Hướng dẫn
-
Hãy quan sát việc gán biến trong cột “Lệnh” và cho biết biến kết quả là “Cục bộ” hay “Toàn cục”:
Lệnh Cục bộ Toàn cục debian=mother
Đúng
Sai
ubuntu=deb-based
Đúng
Sai
mint=ubuntu-based; export mint
Sai
Đúng
export suse=rpm-based
Sai
Đúng
zorin=ubuntu-based
Đúng
Sai
-
Hãy xem “Lệnh” và “Đầu ra” và giải thích ý nghĩa:
Lệnh Đầu ra Ý nghĩa echo $HISTCONTROL
ignoreboth
Cả hai lệnh đều là lệnh lặp và những lệnh bắt đầu bằng dấu cách sẽ không được lưu trong
history
.echo ~
/home/carol
HOME
củacarol
là/home/carol
.echo $DISPLAY
reptilium:0:2
máy
reptilium
có máy chủ X đang chạy và chúng ta đang sử dụng màn hình thứ hai của màn hình.echo $MAILCHECK
60
Email sẽ được kiểm tra mỗi phút.
echo $HISTFILE
/home/carol/.bash_history
history
sẽ được lưu trong/home/carol/.bash_history
. -
Các biến đang được đặt không chính xác trong cột “Lệnh sai”. Hãy điền thông tin còn thiếu trong cột “Lệnh đúng” và “Tham chiếu biến” để có thể nhận được “Đầu ra dự kiến”:
Lệnh sai Lệnh đúng Tham chiếu biến Đầu ra dự kiến lizard =chameleon
lizard=chameleon
echo $lizard
chameleon
cool lizard=chameleon
cool_lizard=chameleon
(ví dụ)echo $cool_lizard
chameleon
lizard=cha|me|leon
lizard="cha|me|leon"
hoặclizard='cha|me|leon'
echo $lizard
cha|me|leon
lizard=/** chameleon **/
lizard="/** chameleon **/"
hoặclizard='/** chameleon **/'
echo "$lizard"
/** chamelon **/
win_path=C:\path\to\dir\
win_path=C:\\path\\to\\dir\\
echo $win_path
C:\path\to\dir\
-
Hãy đọc mục đích và viết lệnh thích hợp:
Mục đích Lệnh Đặt ngôn ngữ của vỏ hiện tại thành UTF-8 tiếng Tây Ban Nha (
es_ES.UTF-8
).LANG=es_ES.UTF-8
.In tên của thư mục làm việc hiện tại.
echo $PWD
hoặcpwd
.Tham chiếu biến môi trường lưu trữ thông tin về các kết nối
ssh
.echo $SSH_CONNECTION
.Đặt
PATH
để/home/carol/scripts
làm thư mục cuối cùng khi tìm kiếm các tệp thực thi.PATH=$PATH:/home/carol/scripts
.Đặt giá trị của
my_path
thànhPATH
.my_path=PATH
.Đặt giá trị của
my_path
thành giá trị củaPATH
.my_path=$PATH
. -
Hãy tạo một biến cục bộ có tên
mammal
và gán cho nó giá trịgnu
:mammal=gnu
-
Bằng cách sử dụng thay thế biến, hãy tạo một biến cục bộ khác có tên
var_sub
với giá trị phù hợp để khi được tham chiếu quaecho $var_sub
, chúng ta sẽ thu được:The value of mammal is gnu
:var_sub="The value of mammal is $mammal"
-
Hãy biến
mammal
thành một biến môi trường:export mammal
-
Hãy tìm nó bằng
set
vàgrep
:set | grep mammal
-
Hãy tìm nó bằng
set
vàgrep
:env | grep mammal
-
Bằng hai lệnh liên tiếp, hãy tạo một biến môi trường có tên
BIRD
và có giá trị làpenguin
:BIRD=penguin; export BIRD
-
Bằng một lệnh duy nhất, hãy tạo một biến môi trường có tên
NEW_BIRD
và có giá trị làyellow-eyed penguin
:export NEW_BIRD="yellow-eyed penguin"
hoặc
export NEW_BIRD='yellow-eyed penguin'
-
Giả sử bạn là
user2
, hãy tạo một thư mục có tên làbin
trong thư mục chính của bạn:mkdir ~/bin
hoặc
mkdir /home/user2/bin
hoặc
mkdir $HOME/bin
-
Hãy nhập lệnh để thêm thư mục
~/bin
vàoPATH
của bạn để nó là thư mục đầu tiênbash
tìm các tệp nhị phân:PATH="$HOME/bin:$PATH"
PATH=~/bin:$PATH
hoặcPATH=/home/user2/bin:$PATH
đều hợp lệ như nhau. -
Để đảm bảo giá trị của
PATH
không bị thay đổi trong các lần khởi động lại, bạn sẽ đặt đoạn mã nào — dưới dạng câu lệnhif
— vào~/.profile
?if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
Đáp án Bài tập Mở rộng
-
let
: hơn cả một lệnh tính biểu thức số học:-
Hãy xem trang hướng dẫn hoặc thực hiện tìm kiếm trên web về
let
và ý nghĩa của nó khi đặt biến và tạo một biến cục bộ mới có tênmy_val
có giá trị là10
— là kết quả của 5 + 5:let "my_val = 5 + 5"
hoặc
let 'my_val = 5 + 5'
-
Bây giờ, hãy tạo một biến khác có tên
your_val
có giá trị là5
— là kết quả của việc chia giá trịmy_val
với 2:let "your_val = $my_val / 2"
hoặc
let 'your_val = $my_val / 2'
-
-
Kết quả của một lệnh nằm trong một biến? Tất nhiên là điều này có thể xảy ra. Nó được gọi là thay thế lệnh. Hãy tìm hiểu và nghiên cứu hàm có tên
music_info
sau:music_info(){ latest_music=`ls -l1t ~/Music | head -n 6` echo -e "Your latest 5 music files:\n$latest_music" }
Kết quả của lệnh
ls -l1t ~/Music | head -n 6
sẽ trở thành giá trị của biếnlatest_music
. Sau đó, biếnlatest_music
sẽ được tham chiếu trong lệnhecho
(xuất ra tổng số byte được chiếm bởi thư mụcMusic
và năm tệp nhạc mới nhất được lưu trữ trong thư mụcMusic
— mỗi tệp một dòng).Lựa chọn nào sau đây đồng nghĩa hợp lệ với
latest_music=`ls -l1t ~/Music | head -n 6`
Lựa chọn A:
latest_music=$(ls -l1t ~/Music| head -n 6)