เชลล์สคริปต์เบื้องต้น ตอนที่ 3 - ตัวแปรสภาพแวดล้อม
www.tanabutr.co.th/photobook
ตัวแปรสภาพแวดล้อม
ตัวแปรที่ใช้ในเชลล์จะมีสองแบบคือตัวแปรธรรมดากับตัวแปรสภาพแวดล้อม (environment variable). ตัวแปรสภาพแวดล้อมจริงๆแล้วก็คือตัวแปรธรรมดาแต่มีผลที่โปรแกรมที่รันในเชลล์นั้นจะสืบทอดตัวแปรสภาพแวดล้อมและค่านั้นไปด้วย. ตัวอย่างตัวแปรสภาพแวดล้อมที่เราคุ้นเคยกันเช่น PATH เป็นต้น.
การสร้างตัวแปรสภาพแวดล้อมเหมือนกับการสร้างตัวแปรทั่วไป. แต่หลังจากที่สร้างตัวแปรทั่วไปแล้วต้องประกาศตัวแปรนั้นให้เป็นตัวแปรสภาพแวดล้อมด้วยคำสั่ง export.
$ MY_ENV_VAR="example of environment variable" $ export MY_ENV_VAR
หรือจะตั้งแค่ตัวแปรและประกาศตัวแปรสภาพแวดล้อมพร้อมๆกันก็ได้.
$ export MY_ENV_VAR="example of environment variable"
ตัวแปรสภาพแวดล้อมมักจำใช้ชื่อตัวแปรเป็นตัวอักษรตัวใหญ่แต่ไม่จำเป็น. เราลองมาดูผลกระทบของตัวแปรสภาพแวดล้อมต่อโปรแกรมที่รันในเชลล์นั้นๆดู.
สมมติว่าเรามีเชลล์สคริปต์ที่แสดงค่าตัวแปรตามตัวอย่างต่อไปนี้.
#!/bin/sh # file: env.sh echo $MY_ENV_VAR echo $MY_VAR
เชลล์สคริปต์นี้ไม่ได้ทำอะไรพิสดาร, แค่แสดงค่าของตัวแปร MY_ENV_VAR กับ MY_VAR เท่านั้น. ที่นี้เราลองรันในเชลล์ที่มีตัวแปรสภาพแวดล้อม MY_ENV_VAR และตัวแปรธรรมดา MY_VAR ดูว่าจะได้ผลอย่างไรดู.
$ export MY_ENV_VAR="example of environment variable" $ MY_VAR="Normal variable" $ ./env.sh example of environment variable $ . env.sh example of environment variable Normal variable
ผลของการรันเชลล์สคริปต์จะไม่เหมือนกัน. ทำไม? การรันเชลล์สคริปต์แบบแรกเชลล์ที่รันอยู่จะเรียกเชลล์ตัวใหม่ (สร้างโปรเซสใหม่) และเชลล์ตัวใหม่จะเป็นตัวกระทำการ. เชลล์ตัวใหม่ในที่นี้คือบรรทัด #!/bin/sh นั่นเอง. เชลล์ (โปรแกรม) ที่เกิดใหม่สืบทอดตัวแปรสภาพแวดล้อม MY_ENV_VAR มาด้วยทำให้แสดงผลได้. แต่ไม่สามารถแสดงค่าของตัวแปร MY_VAR ได้เพราะไม่ใช้ตัวแปรสภาพแวดล้อม (ไม่สืบทอดไปสู่โปรแกรมอื่น).
ส่วนการรันเชลล์สคริปต์แบบที่สองโดยใช้ "." (dot). เป็นการใช้เชลล์ที่ทำงานอยู่ในปัจจุบันอ่านไฟล์ env.sh ไม่ได้เป็นการสร้างเชลล์ใหม่. ดังนั้นจึงสามารถแสดงค่าของตัวแปรทั้งสองตัวได้. คำสั่งที่เทียบเท่ากับ "." คือ source ใช้สำหรับอ่านข้อมูลเข้าไปในเชลล์ที่ใช้อยู่. ตัวอย่างเช่นในไฟล์ ~/.bashrc มักจะตั้งค่าตัวแปรต่างๆไว้. ไฟล์นี้จะถูกอ่าน (ถูกกระทำการ) ตอนที่เชลล์เริ่มทำงาน. ถ้ามีการแก้ไขไฟล์นี้แล้วอยากให้มีผลทันทีโดยไม่ต้องเริ่มเชลล์ใหม่ก็เพิ่งแค่ source ~/.bashrc เรียกอ่านเนื้อหาในไฟล์นั้นโดยใช้เชลล์ที่ทำงานอยู่ในปัจจุบัน.
ดูค่าตัวแปรสภาพแวดล้อม
เราจะรู้ได้อย่างไรว่ามีตัวแปรสภาพแวดล้อมอะไรบ้างในขณะนี้? คำสั่งที่ใช้บอกตัวแปรสภาพแวดล้อมก็คือคำสั่งเดียวกันกับที่ใช้ประกาศตัวแปรสภาพแวดล้อมซึ่งก็คือ export.
$ export declare -x CC="gcc" declare -x CLASSPATH="/opt/blackdown-jdk-1.4.1/jre/lib/rt.jar:." declare -x COLORTERM="gnome-terminal" declare -x CONFIG_PROTECT="/var/bind /usr/lib/mozilla/defaults/pref /usr/X11R6/lib/X11/xkb /usr/kde/3.2/share/config /usr/kde/3.1/share/config /usr/share/texmf/tex/generic/config/ /usr/share/texmf/tex/platex/config/ /usr/share/texmf/dvips/config/ /usr/share/texmf/dvipdfm/config/ /usr/share/texmf/xdvi/ /usr/share/config" declare -x CONFIG_PROTECT_MASK="/etc/gconf /etc/terminfo" declare -x CVSROOT=":pserver:poonlap@linux.thai.net:/home/cvs" declare -x CVS_RSH="ssh" declare -x CXX="g++" declare -x DESKTOP_SESSION="gnome" declare -x DISPLAY=":0.0" declare -x EDITOR="/usr/bin/vim" declare -x GDK_USE_XFT="1" declare -x GDMSESSION="gnome" declare -x GLIBC_SSP_CHECKED="1" declare -x GNOME_DESKTOP_SESSION_ID="Default" declare -x GNOME_KEYRING_SOCKET="/tmp/keyring-N1Rd2c/socket" declare -x GTK_RC_FILES="/etc/gtk/gtkrc:/home/poonlap/.gtkrc-1.2-gnome2" declare -x GUILE_LOAD_PATH="/usr/share/guile/1.6" declare -x G_BROKEN_FILENAMES="1" declare -x HOME="/home/poonlap" declare -x HOSTNAME="justice" declare -x INFODIR="/usr/share/info" declare -x INFOPATH="/usr/share/info:/usr/share/gcc-data/i686-pc-linux-gnu/3.3 /info" declare -x INPUTRC="/etc/inputrc" declare -x JAVAC="/opt/blackdown-jdk-1.4.1/bin/javac" declare -x JAVA_HOME="/opt/blackdown-jdk-1.4.1" declare -x JDK_HOME="/opt/blackdown-jdk-1.4.1" declare -x KDEDIR="/usr/kde/3.2" declare -x KDEDIRS="/usr" declare -x LESS="-R" declare -x LESSOPEN="|lesspipe.sh %s" declare -x LOGNAME="poonlap" declare -x LS_COLORS="no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01 :cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*. com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01; 31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01; 31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.rar=01;31:*.ace= 01;31:*.zoo=01;31:*.cpio=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35 :*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png =01;35:*.mng=01;35:*.xcf=01;35:*.pcx=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35 :*.avi=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.mov =01;35:*.qt=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:* .fli=01;35:*.gl=01;35:*.dl=01;35:" declare -x MANPATH="/usr/share/man:/usr/local/share/man:/usr/share/gcc-data/i686-pc-linux- gnu/3.3/man:/usr/share/man:/opt/blackdown-jdk-1.4.1/man:/usr/qt/3/doc/man:/opt/ vmware/man" declare -x MOZILLA_FIVE_HOME="/usr/lib/mozilla" declare -x MY_ENV_VAR="example of environment variable" declare -x OLDPWD="/home/poonlap" declare -x PAGER="/usr/bin/less" declare -x PATH="/bin:/usr/bin:/usr/local/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/3.3: /opt/Acrobat5:/usr/X11R6/bin:/opt/blackdown-jdk-1.4.1/bin:/opt/blackdown-jdk-1. 4.1/jre/bin:/usr/qt/3/bin:/usr/kde/3.2/bin:/usr/kde/3.1/bin:/opt/firebird/bin: /opt/vmware/bin" declare -x PS1="\\[\\033[01;32m\\]\\u@\\h \\[\\033[01;34m\\]\\W \\\$ \\[\\033[0 0m\\]" declare -x PWD="/home/poonlap/tmp" declare -x QMAKESPEC="linux-g++" declare -x QTDIR="/usr/qt/3" declare -x SESSION_MANAGER="local/justice:/tmp/.ICE-unix/7010" declare -x SHELL="/bin/bash" declare -x SHLVL="1" declare -x SSH_AGENT_PID="7031" declare -x SSH_AUTH_SOCK="/tmp/ssh-mqxqiU7010/agent.7010" declare -x TERM="xterm" declare -x USER="poonlap" declare -x USERNAME="poonlap" declare -x WINDOWID="21507072" declare -x XAUTHORITY="/home/poonlap/.Xauthority" declare -x XINITRC="/etc/X11/xinit/xinitrc" declare -x XPSERVERLIST=""
จากตัวอย่างจะเห็นว่ามีตัวแปรสภาพแวดล้อมมากมายที่ตั้วค่าไว้อัตโนมัติในระบบ. คำสั่งที่ใช้แสดงตัวแปรสภาพแวดล้อมและค่าอีกคำสั่งคือ printenv.
ถ้าต้องการเปลี่ยนตัวแปรสภาพแวดล้อมเป็นตัวแปรธรรมดาก็ใช้ตัวเลือก -n ร่วมกับคำสั่ง export เช่น.
$ export -n MY_ENV_VAR