ThaiTux.info - shell script https://www.thaitux.info/taxonomy/term/261 13. การค้นหาที่ผิดในสคริปต์ https://www.thaitux.info/node/379 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>เราใช้พารามิเตอร์ <code>-x</code> ต่อท้ายคำสั่งในบรรทัดแรก</p> <pre>#!/bin/bash -x</pre><p> จะมีผลว่าเชลล์จะแสดงทุกคำสั่งที่ถูกรันออกมาทางจอภาพ</p> <p>จบแล้วจ้า</p> </div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:52:42 +0000 wd 379 at https://www.thaitux.info https://www.thaitux.info/node/379#comments 12.ตัวอย่างสคริปต์ https://www.thaitux.info/node/378 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><h4>12.1 ตัวอย่างสคริปต์ดูรายชื่อไฟล์ในไดเรคทอรี่ย่อย</h4> <pre>#!/bin/bash function listdir { local PAT="$1" local ROOT="$2" for i in *; do if [ -d "$i" ]; then local CUR="$ROOT/$i" pushd "$i" &amp;&gt;/dev/null listdir "$PAT" "$CUR" popd &amp;&gt;/dev/null fi done if [ ! -z "$( ls -d $PAT 2&gt;/dev/null )" ]; then echo "Directory: $ROOT" ls -d $PAT 2&gt;/dev/null echo fi } if [ -z "$1" ]; then echo List file in PATTERN recursive into directories. echo Usage: $0 "PATTERN" exit fi PATTERN="$1" echo "List $PATTERN" listdir "$PATTERN" "."</pre><p>ให้ผลคล้ายคำสั่ง</p> <pre>$ <strong>find * -name PATTERN</strong></pre><h4>12.2 ตัวอย่างสคริปต์บีบอัดสำรองข้อมูล</h4> <pre>#!/bin/bash SRCD="/home/" TGTD="/var/backups/" OF=home-$(date +%Y%m%d).tgz tar -cZf $TGTD$OF $SRCD</pre><h4>12.3 เปลี่ยนชื่อไฟล์ทีละหลายไฟล์</h4> <pre>#!/bin/sh # renna: rename multiple files according to several rules # written by felix hudson Jan - 2000 #first check for the various 'modes' that this program has #if the first ($1) condition matches then we execute that portion of the #program and then exit # check for the prefix condition if [ $1 = p ]; then #we now get rid of the mode ($1) variable and prefix ($2) prefix=$2 ; shift ; shift # a quick check to see if any files were given # if none then its better not to do anything than rename some non-existent # files!! if [$1 = ]; then echo "no files given" exit 0 fi # this for loop iterates through all of the files that we gave the program # it does one rename per file given for file in $* do mv ${file} $prefix$file done #we now exit the program exit 0 fi # check for a suffix rename # the rest of this part is virtually identical to the previous section # please see those notes if [ $1 = s ]; then suffix=$2 ; shift ; shift if [$1 = ]; then echo "no files given" exit 0 fi for file in $* do mv ${file} $file$suffix done exit 0 fi # check for the replacement rename if [ $1 = r ]; then shift # i included this bit as to not damage any files if the user does not specify # anything to be done # just a safety measure if [ $# -lt 3 ] ; then echo "usage: renna r [expression] [replacement] files... " exit 0 fi # remove other information OLD=$1 ; NEW=$2 ; shift ; shift # this for loop iterates through all of the files that we give the program # it does one rename per file given using the program 'sed' # this is a sinple command line program that parses standard input and # replaces a set expression with a give string # here we pass it the file name ( as standard input) and replace the nessesary # text for file in $* do new=`echo ${file} | sed s/${OLD}/${NEW}/g` mv ${file} $new done exit 0 fi # if we have reached here then nothing proper was passed to the program # so we tell the user how to use it echo "usage;" echo " renna p [prefix] files.." echo " renna s [suffix] files.." echo " renna r [expression] [replacement] files.." exit 0 # done!</pre><h4>12.4 เปลี่ยนชื่อไฟล์แบบง่าย</h4> <pre>#!/bin/bash # renames.sh # basic file renamer criteria=$1 re_match=$2 replace=$3 for i in $( ls *$criteria* ); do src=$i tgt=$(echo $i | sed -e "s/$re_match/$replace/") mv $src $tgt done</pre></div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:51:53 +0000 wd 378 at https://www.thaitux.info https://www.thaitux.info/node/378#comments 11. ตัวดำเนินการ (operators) และคำสั่งน่าสนใจ https://www.thaitux.info/node/377 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><h4>11.1 ตัวดำเนินการเปรียบเทียบตัวอักษร (String comparison operators)</h4> <ul> <li><code><strong>[ "$s1" = "$s2" ]</strong></code> หรือ <code><strong>[ "$s1" == "$s2" ]</strong></code> เป็นจริง ถ้า s1 เท่ากับ s2</li> <li><code><strong>[ "$s1" != "$s2" ]</strong></code> เป็นจริง ถ้า s1 ไม่เท่ากับ s2</li> <li><code><strong>[[ "$s1" &lt; "$s2" ]]</strong></code> หรือ <strong><code>[ "$s1" \&lt; "$s2" ]</code></strong> เป็นจริง ถ้า s1 น้อยกว่า s2</li> <li><code><strong>[[ "$s1" &gt; "$s2" ]]</strong></code> หรือ <strong><code>[ "$s1" \&gt; "$s2" ]</code></strong> เป็นจริง ถ้า s1 มากกว่า s2</li> <li><code><strong>[ -n "$s1" ]</strong></code> เป็นจริง ถ้า s1 มีค่าใด ๆ</li> <li><code><strong>[ -z "$s1" ]</strong></code> เป็นจริง ถ้า s1 ไม่มีค่า</li> </ul> <h4>11.2 ตัวอย่างการเปรียบเทียบอักษร</h4> <pre>#!/bin/bash S1='string' S2='String' if [ "$S1"="$S2" ]; then echo "S1('$S1') is not equal to S2('$S2')" fi if [ "$S1"="$S1" ]; then echo "S1('$S1') is equal to S1('$S1')" fi</pre><h4>11.3 ตัวดำเนินการทางคณิตศาลตร์ (Arithmetic operators)</h4> <ul> <li><code><strong>+</strong></code> การบวก</li> <li><code><strong>-</strong></code> การลบ</li> <li><code><strong>*</strong></code> การคูณ</li> <li><code><strong>/</strong></code> การหาร</li> <li><code><strong>%</strong></code> การหาเศษจากตัวหาร (remainder)</li> </ul> <h4>11.4 ตัวเปรียบเทียบทางคณิตศาตร์ (Arithmetic relational operators</h4> <ul> <li><code><strong>-lt</strong></code> น้อยกว่า (&lt;)</li> <li><code><strong>-gt</strong></code> มากกว่า (&gt;)</li> <li><code><strong>-le</strong></code> น้อยกว่าหรือเท่ากับ (&lt;=)</li> <li><code><strong>-ge</strong></code> มากกว่าหรือเท่ากับ (&gt;=)</li> <li><code><strong>-eq</strong></code> เท่ากับ (==)</li> <li><code><strong>-ne</strong></code> ไม่เท่ากับ (!=) </li> </ul> <h4>11.5 คำสั่งควรรู้</h4> <dt><strong>sed</strong> (stream editor)</dt> <dd><code>sed</code> เป็นเอดิเตอร์แบบบรรทัดคำสั่ง มีการใช้งานที่พลิกแพลงหลากหลายมาก ตัวอย่าง <pre>$ <strong>sed 's/old/new/g' /tmp/dummy</strong></pre><p>นำเอาเนื้อไฟล์ <code>/tmp/dummy</code> มาแทนที่ <code>old</code> ด้วย <code>new</code> และแสดงออกทางจอภาพ</p> <pre>$ <strong>sed 12,18d /tmp/dummy</strong></pre><p>นำเอาเนื้อไฟล์ <code>/tmp/dummy</code> มาแสดงทางจอภาพ โดยเว้นไม่แสดงบรรทัดที่ 12 ถึงบรรทัดที่ 18</p> <p>ดูรายละเอียดเพิ่มเติมได้ที่ <a href="http://www.gentoo.org/doc/en/articles/l-sed1.xml">gentoo: Sed by example</a><br /> </p></dd> <dt><strong>awk</strong> (manipulation of datafiles, text retrieval and processing)</dt> <dd><code>awk</code> เป็นทั้งโปรแกรมและภาษาในการค้นหาข้อความในไฟล์จากรูปแบบที่เรากำหนดให้<br /> สมมุติว่าไฟล์ <code>/tmp/dummy</code> มีเนื้อไฟล์คือ <pre>test123 test tteesstt</pre><p>ตัวอย่างการใช้งานคือ</p> <pre>$ <strong>awk '/test/ {print}' /tmp/dummy</strong> test123 test </pre><p> ดูรายละเอียดเพิ่มเติมได้ที่ <a href="http://www.gentoo.org/doc/en/articles/l-awk1.xml">gentoo: Awk by example</a><br /> </p></dd> <dt><strong>grep</strong> (print lines matching a search pattern)</dt> <dd><code>grep</code> เป็นโปรแกรมที่ใช้บ่อยในการค้นข้อความในไฟล์ และยังมีความสามารถในการสรุปผลการนับข้อความด้วย<br /> ตัวอย่าง <pre>$ <strong>man grep | grep "standard" -c</strong> 8</pre><p>เป็นการค้นคำว่า standard ในการแสดงผลของคำสั่ง <code>man grep</code> ว่ามีอยู่กี่คำ คำตอบคือ 8</p> <p>ดูตัวอย่างเพิ่มเติมที่ <a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_02.html">tdlp: Examples using grep</a><br /> </p></dd> <dt><strong>wc</strong> (counts lines, words and bytes)</dt> <dd><code>wc</code> ใช้ในการนับคำ, นับบรรทัด และนับจำนวนหน่วยความจำที่ถูกใช้ในไฟล์ เป็นไบต์<br /> ตัวอย่าง <pre>$ <strong>wc --words --lines --bytes /tmp/dummy</strong> 3 3 22 /tmp/dummy</pre></dd> <dt><strong>sort</strong> (sort lines of text files)</dt> <dd><code>sort</code> ใช้จัดเรียงข้อมูล<br /> สมมุติว่าไฟล์ /tmp/dummy มีเนื้อว่า <pre>b c a</pre><p> ตัวอย่างคำสั่งคือ</p> <pre>$ <strong>sort /tmp/dummy</strong> a b c</pre><p>คือการนำเอาเนื้อไฟล์ <code>/tmp/dummy</code> มาจัดเรียง และแสดงผลออกทางจอภาพ<br /> </p></dd> <dt><strong>bc</strong> (a calculator programming language)</dt> <dd><code>bc</code> เป็นเครื่องคิดเลขแบบใช้บรรทัดคำสั่ง<br /> ตัวอย่างเช่น <pre>$ <strong>echo 1+1</strong> 1+1 $ <strong>echo 1+1 | bc</strong> 2</pre><p> หรือใช้แบบโต้ตอบ</p> <pre>$ <strong>bc -q</strong> <strong>1 == 5</strong> 0 <strong>0.05 == 0.05</strong> 1 <strong>5 != 5</strong> 0 <strong>2 ^ 8</strong> 256 <strong>sqrt(9)</strong> 3 <strong>while (i != 9) { i = i + 1; print i }</strong> 123456789 <strong>quit</strong> </pre></dd> <dt><strong>tput</strong> (initialize a terminal or query terminfo database) </dt> <dd><code>tput</code> ใช้ในการตั้งค่าหรือแสดงค่าต่าง ๆ ของเทอร์มินัล<br /> เช่น <pre>$ <strong>tput cup 10 4</strong></pre><p>เลื่อนเคอร์เซอร์ไปยังบรรทัดที่ 10 สดมภ์ที่ 4</p> <pre>$ <strong>tput reset</strong></pre><p>ล้างจอภาพ มีค่าเท่ากับคำสั่ง <code>clear</code></p> <pre>$ <strong>tput cols</strong></pre><p>แสดงจำนวนสดมภ์ (ความกว้าง) ของจอเทอร์มินัล<br /> </p></dd> </div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:49:47 +0000 wd 377 at https://www.thaitux.info https://www.thaitux.info/node/377#comments 10.เกร็ดอื่น ๆ https://www.thaitux.info/node/376 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><pre>10.1 การสั่งรันสคริปต์และคำสั่ง <code>source</code></pre><p>การสั่งรันสคริปต์ในเชลล์ มีเกร็ดคือ</p> <ul> <li>ถ้าเราใส่ชื่อสคริปต์พร้อมพาธ เชลล์จะค้นหาสคริปต์จากชื่อเต็มที่เราใส่ เช่น<br /> <pre>$ <strong>/bin/ls</strong></pre></li> <li>ถ้าเราใส่ชื่อสคริปต์โดด ๆ เชลล์จะค้นหาสคริปต์จากตัวแปร <code>$PATH</code> โดยไม่สนใจไดเรคทอรี่ปัจจุบัน เช่น<br /> <pre>$ <strong>mycode</strong></pre><p>หากค้นไม่พบ จะแสดงข้อผิดพลาด<br /> แต่หากต้องการสั่งรันสคริปต์ในไดเรคทอรี่ปัจจุบัน เราต้องใช้คำสั่งอ้างอิงคือ</p> <pre>$ <strong>./mycode</strong></pre></li> </ul> <p>เมื่อสคริปต์ถูกรันจนจบแล้ว ค่าของตัวแปรต่าง ๆ ในสคริปต์จะถูกลบไปด้วย ยกเว้นถ้าเราใช้คำสั่ง <code>source</code> หรือคำสั่ง <code>.</code><br /> เชลล์จะรันคำสั่งนั้นโดยถือเสมือนเป็นสภาพแวดล้อมเดียวกัน ดังนั้นค่าตัวแปรต่าง ๆ ในสคริปต์จะยังคงค้างอยู่ในเชลล์<br /> โดยเมื่อใช้คำสั่งนี้แล้ว การค้นหาสคริปต์ เชลล์จะค้นหาจากตัวแปร <code>$PATH</code> ก่อน ตามด้วยไดเรคทอรี่ปัจจุบันด้วย<br /> เช่น ถ้าสคริปต์ mycode มีเนื้อไฟล์เป็น</p> <pre>#!/bin/bash ABC="This is new ABC"</pre><p> ทดลองรันได้ดังนี้</p> <pre>$ <strong>ABC="Old ABC"</strong> $ <strong>echo $ABC</strong> Old ABC $ <strong>./mycode</strong> $ <strong>echo $ABC</strong> Old ABC $ <strong>. mycode</strong> $ <strong>echo $ABC</strong> This is new ABC</pre><h4>10.2 การแทนค่าตัวเลข</h4> <p>เราใช้ <code>$((ARITHMATIC))</code> หรือ <code>$[ARITHMATIC]</code> ในการแทนค่าตัวแปร<br /> ดังนี้</p> <pre>$ <strong>echo $(1+1)</strong> bash: 1+1: command not found $ <strong>echo 1+1</strong> 1+1 $ <strong>echo $((1+1))</strong> 2 $ <strong>echo $[1+1]</strong> 2</pre><h4>10.3 bash อยู่ที่ไหน</h4> <p>บรรทัดเริ่มต้นของสคริปต์ หลังเครื่องหมาย <code>#!</code> (hash-bang) เราต้องใส่พาธของโปรแกรม bash ให้เต็ม<br /> สำหรับเดเบียน อยู่ที่ <code>/bin/bash</code> อยู่แล้ว แต่หากเป็นดิสโตรอื่น อาจค้นหาว่าโปรแกรม bash อยู่ที่ไหน โดยใช้คำสั่งเหล่านี้</p> <pre>$ <strong>which bash</strong> $ <strong>whereis bash</strong> $ <strong>find / -name bash</strong></pre><h4>10.4 ดูค่าที่โปรแกรมส่งออกมา</h4> <p>หลายโปรแกรมของเชลล์มีการส่งค่าออกมา (Return value) อาจเพื่อแจ้งสถานะการรันว่ารันสำเร็จหรือไม่อย่างไร หรืออาจส่งออกเป็นค่าที่จะนำไปประมวลผลต่อก็ตาม เราสามารถใช้ตัวแปรพิเศษ <code>$?</code> ในการดูผลลัพธ์ของโปรแกรมได้<br /> เช่น</p> <pre>#!/bin/bash cd /dada &amp;&gt; /dev/null echo rv: $? cd $(pwd) &amp;&gt; /dev/null echo rv: $?</pre><p>กรณีนี้ ไดเรคทอรี่ <code>/dada</code> เป็นไดเรคทอรี่ที่เราแกล้งพิมพ์ผิดไว้ เพื่อดูว่าสคริปต์จะส่งออกค่าออกมาเป็นอย่างไร ซึ่งจะได้ผลออกมาเป็น 1 และ 0 ตามลำดับ คือ 1 หมายถึงมีข้อผิดพลาดในโปรแกรม และ 0 หมายถึงรันสำเร็จ ไม่มีข้อผิดพลาดใด ๆ</p> <h4>10.5 จับการแสดงผลใส่ตัวแปร</h4> <p>เราสามารถนำผลลัพธ์ของโปรแกรมมาใส่ในตัวแปร ด้วยการสั่งภายใต้เครื่องหมาย <code>`<code> (grave accent)<br /> เช่น</code></code></p> <pre>#!/bin/bash DBS=`mysql -u root -e "show databases"` for b in $DBS ; do mysql -u root -e "show tables from $b" done</pre><p>เป็นการนำผลลัพธ์ของคำสั่งแรกคือ <code>mysql -u root -e "show databases"</code> มาใส่ในตัวแปร <code>DBS</code> เพื่อทำเป็นขอบเขตให้กับตัวแปร <code>b</code> ในคำสั่ง <code>for</code> อีกครั้งหนึ่ง<br /> ตามตัวอย่างจะแสดงผลทุกตารางในทุกฐานข้อมูลของ mysql</p> </div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:47:32 +0000 wd 376 at https://www.thaitux.info https://www.thaitux.info/node/376#comments 9.การติดต่อผู้ใช้ (User Interfaces) https://www.thaitux.info/node/375 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><h4>9.1 ใช้คำสั่ง <code>select</code> ในการสร้างหัวข้อให้เลือก</h4> <pre>#!/bin/bash OPTIONS="Hello Quit" select opt in $OPTIONS; do if [ "$opt" = "Quit" ]; then echo done exit elif [ "$opt" = "Hello" ]; then echo Hello World else clear echo bad option fi done</pre><p>ตัวอย่างนี้จะสร้างหัวข้อ 1) และ 2) จากตัวแปร <code>OPTIONS</code> เพื่อมาให้เลือก โดยจะวนรอบถามไปเรื่อย ๆ จนกว่าจะพบคำสั่ง <code>exit</code> ให้ออกจากการวนรอบ</p> <h4>9.2 ใช้การตรวจสอบว่ามีการใส่ค่าพารามิเตอร์หรือไม่</h4> <pre>#!/bin/bash if [ -z "$1" ]; then echo usage: $0 directory exit fi SRCD=$1 TGTD="/var/backups/" OF=home-$(date +%Y%m%d).tgz tar -cZf $TGTD$OF $SRCD</pre><p>บรรทัดที่ 2 จะตรวจว่ามีการใส่พารามิเตอร์ให้กับโปรแกรมหรือไม่ (<code>if [ -z "$1" ]</code> -z หมายถึงการตรวจสอบว่ามีค่าหรือไม่)<br /> ถ้าไม่มีการใส่ค่าพารามิเตอร์ โปรแกรมจะทำคำสั่งในบรรทัดที่ 3 คือแสดงการใช้งาน (<code>$0</code> คือชื่อโปรแกรมนี้) และบรรทัดที่ 4 คือออกจากโปรแกรม<br /> แต่ถ้ามีการใส่ค่าพารามิเตอร์ถูกต้อง ก็จะทำบรรทัดที่ 6 ต่อไปจนจบ ซึ่งในที่นี้คือการบีบอัดทำสำเนาให้กับไดเรกทอรี่ที่เราให้เป็นพารามิเตอร์ (<code>$1</code>) ในชื่อไฟล์ว่า <code>/var/backups/home-YYYYMMDD</code></p> <h4>9.3 หยุดถามผู้ใช้ด้วยคำสัง <code>read</code></h4> <pre>#!/bin/bash echo Please, enter your name read NAME echo "Hi $NAME!"</pre><p>สังเกตุการใช้คำสั่ง <code>read</code> กำหนดค่าให้ตัวแปร <code>NAME</code> ไม่ต้องใช้เครื่องหมาย <code>$</code> นำหน้าตัวแปร</p> <p>อาจรอรับค่าทีละหลายตัวแปรได้ด้วย โดยคั่นแต่ละตัวแปรด้วยช่องว่าง</p> <pre>#!/bin/bash echo Please, enter your firstname and lastname read FN LN echo "Hi! $LN, $FN !"</pre></div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:45:53 +0000 wd 375 at https://www.thaitux.info https://www.thaitux.info/node/375#comments 8.ฟังก์ชั่น (functions) https://www.thaitux.info/node/374 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>ในการใช้งานเชลล์สคริปต์แบบจริงจัง เราจำเป็นต้องเขียนฟังก์ชั่นเพื่อประโยชน์ในการเรียกใช้งานแบบซ้ำ ๆ เพื่อให้ประหยัดการเขียนโค๊ด และให้โค๊ดดูง่าย<br /> มีรูปแบบเป็น</p> <pre>function FUNCTION_NAME { COMMAND }</pre><p>หรือ</p> <pre> FUNCTION_NAME () { COMMAND }</pre><p>โปรแกรมจะเว้นไม่ถูกเรียกทำงานในช่วงตั้งแต่ชื่อฟังก์ชั่นจนกระทั่งจบบล๊อก <code>{ COMMAND }</code><br /> เรานิยมวางฟังก์ชั่นไว้ที่ต้นโปรแกรม เพื่อให้สามารถถูกเรียกจากโค๊ดหลักได้</p> <h4>8.1 ตัวอย่างฟังก์ชั่น</h4> <pre>#!/bin/bash function quit { exit } function hello { echo Hello! } hello quit echo foo</pre><p>ตัวอย่างนี้ บรรทัดที่ 10 คือคำสั่ง <code>echo foo</code> จะไม่ถูกเรียกใช้ เนื่องจากโปรแกรมจะหลุดสู่เชลล์ในบรรทัดที่ 9 คือคำสั่ง <code>quit</code></p> <h4>8.2 ตัวอย่างฟังก์ชั่นที่มีการส่งผ่านค่าตัวแปร</h4> <pre>#!/bin/bash function quit { exit } function ex { echo $1 } ex Hello ex World quit echo foo</pre><p>จากตัวอย่าง จะเห็นการส่งผ่านข้อความเข้าไปในฟังก์ชั่น <code>ex</code> ด้วยตัวแปร <code>$1</code><br /> ในทำนองเดียวกัน ถ้ามีการส่งผ่านตัวแปรหลายตัว ก็จะใช้รูปแบบเป็น <code>$2, $3, ...</code><br /> โดยเรียกใช้งานด้วยรูปแบบ <code>ex VAR1 VAR2 VAR3 ...</code> ตามลำดับ</p> </div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:44:58 +0000 wd 374 at https://www.thaitux.info https://www.thaitux.info/node/374#comments 7.การวนรอบ โดยใช้คำสั่ง for, while และ until https://www.thaitux.info/node/373 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>คำสั่ง <code>for</code> มีลักษณะคล้าย for ในภาษาไพธอน มีรูปแบบเป็น</p> <pre> for VAR in SCOPE; do COMMAND done</pre><p>คำสั่ง <code>while</code> มีรูปแบบเป็น</p> <pre> while [CONDITION]; do COMMAND done</pre><p>ถ้าเงื่อนไข CONDITION เป็นจริง ก็จะทำคำสั่ง COMMAND คำสั่ง <code>until</code> รูปแบบตรงกันข้ามกับ while โดยมีรูปแบบเป็น</p> <pre> until [CONDITION]; do COMMAND done</pre><p>คือจะทำคำสั่ง COMMAND จนกว่าเงื่อนไข CONDITION จะเป็นจริง<br /> </p><h4>7.1 ตัวอย่าง <code>for</code></h4> <pre> #!/bin/bash for i in $( ls ); do echo item: $i done</pre><p>เป็นการนำคำสั่ง <code>ls</code> ไปเป็นตัวแปรชั่วคราวในการกำหนดขอบเขตให้กับตัวแปร <code>i</code> ในคำสั่ง <code>for</code> ในที่นี้จะทำการแสดงผลว่า <code>item: FILENAME ...</code><br /> </p><h4>7.2 ตัวอย่าง <code>for</code> อีกแบบ</h4> <pre> #!/bin/bash for i in `seq 1 10`; do echo $i done</pre><p>เป็นการนำผลจากคำสั่ง <code>seq 1 10</code> ไปกำหนดขอบเขตให้กับตัวแปร <code>i</code> ในคำสั่ง <code>for</code> อาจเขียนเลียนแบบตัวอย่าง 7.1 ได้เหมือนกันดังนี้</p> <pre> #!/bin/bash for i in $( seq 1 10 ); do echo $i done</pre><h4>7.3 ตัวอย่าง <code>while</code></h4> <pre> #!/bin/bash COUNTER=0 while [ $COUNTER -lt 10 ]; do echo The counter is $COUNTER let COUNTER=COUNTER+1 done</pre><p>เป็นการแสดงค่าตัวแปร <code>COUNTER</code> ที่เพิ่มขึ้นทีละ 1 จาก 0 ถึง 9 โปรดสังเกตุการใช้ตัวแปรเก็บค่าตัวเลข, การเปรียบเทียบตัวเลขโดยใช้ตัวเปรียบเทียบ <code>-lt</code> (less than) และการกำหนดเพิ่มค่าให้กับตัวแปรแบบตัวเลขโดยใช้คำสั่ง <code>let</code><br /> </p><h4>7.4 ตัวอย่าง <code>until</code></h4> <pre> #!/bin/bash COUNTER=20 until [ $COUNTER -lt 10 ]; do echo COUNTER $COUNTER let COUNTER-=1 done</pre><p>จะแสดงตัวเลขตั้งแต่ 20 ลดลงทีละ 1 จนถึง 10</p> </div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:43:50 +0000 wd 373 at https://www.thaitux.info https://www.thaitux.info/node/373#comments 6. ประโยคเงื่อนไข https://www.thaitux.info/node/372 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><h4>6.1 รูปแบบ</h4> <p>มีรูปแบบคือ</p> <pre>if [EXPRESSION]; then CODE IF 'EXPRESSION' IS TRUE. <em>[</em>elif [EXPRESSION-ELIF]; then CODE IF 'EXPRESSION-ELIF' IS TRUE.<em>]</em> <em>[</em>else CODE IF NOTHING IS TRUE.<em>]</em> fi</pre><h4>6.2 ตัวอย่าง <code>if ... then</code></h4> <pre>#!/bin/bash if [ "foo" = "foo" ]; then echo expression evaluated as true fi</pre><p> โค๊ดนี้จะเป็นจริงเสมอ ดังนั้นข้อความ "<code>expression evaluated as true</code>" จะถูกพิมพ์ออกมาเสมอ</p> <h4>6.3 ตัวอย่าง <code>if ... then ... else</code></h4> <pre>#!/bin/bash if [ "foo" = "foo" ]; then echo expression evaluated as true else echo expression evaluated as false fi</pre><p> โค๊ดนี้จะเป็นจริงเสมอ ดังนั้นข้อความ "<code>expression evaluated as true</code>" จะถูกพิมพ์ออกมาเสมอ</p> <h4>6.4 ตัวอย่างแบบใช้ตัวแปร</h4> <pre>#!/bin/bash T1="foo" T2="bar" if [ "$T1" = "$T2" ]; then echo expression evaluated as true else echo expression evaluated as false fi</pre><p> ตัวอย่างนี้จะเป็นเท็จเสมอ<br /> สังเกตุการใช้ตัวแปรในการเปรียบเทียบ ควรให้ตัวแปรอยู่ในเครื่องหมายคำพูดเสมอ เพื่อป้องการการผิดพลาดจากการแทนค่าที่ซับซ้อน หรือการที่มีช่องว่างในค่าตัวแปร</p> </div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:42:51 +0000 wd 372 at https://www.thaitux.info https://www.thaitux.info/node/372#comments 5. ตัวแปร (Variables) https://www.thaitux.info/node/371 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>ตัวแปรในเชลล์สคริปต์ ไม่มีชนิดข้อมูล คือเราสามารถใช้ตัวแปรแทนตัวเลขหรืออักขระใด ๆ ก็ได้<br /> โดยในขั้นตอนกำหนดค่า ไม่ต้องใช้เครื่องหมายใด ๆ นำหน้า แต่ตอนอ้างถึง ต้องใช้เครื่องหมาย <code>$</code> นำหน้าตัวแปร</p> <h4>5.1 ตัวอย่างสคริปต์ Hello World แบบใช้ตัวแปร</h4> <pre>#!/bin/bash STR="Hello World!" echo $STR</pre><p> ให้ผลลัพธ์เหมือนตัวอย่างที่ 2.1<br /> ข้อควรระวังคือ</p> <ul> <li>การกำหนดค่าให้ตัวแปร อย่าเว้นวรรคระหว่างตัวแปรกับเครื่องหมาย <code>=</code></li> <li>หากลืมใส่เครื่องหมาย <code>$</code> จะหมายถึงการแสดงผลข้อความว่า <code>STR</code> เฉย ๆ</li> </ul> <h4>5.2 ตัวอย่างสคริปต์สำรองข้อมูลแบบใช้ตัวแปร</h4> <pre>#!/bin/bash OF=/tmp/my-backup-$(date +%Y%m%d).tgz tar -cvzf $OF /home/USER/</pre><p> ให้ผลลัพธ์คล้ายตัวอย่าง 2.2 แต่เพิ่มการใช้ตัวแปรลอยในคำสั่ง <code>$(date +%Y%m%d)</code> ซึ่งมีผลทำให้ชื่อไฟล์ข้อมูลสำรองมีวันที่ต่อท้ายชื่อด้วย</p> <h4>5.3 ตัวแปรท้องถิ่น</h4> <p>ตัวแปรในเชลล์สคริปต์ทุกตัว จะเป็นตัวแปรรวม (Global) คือทุก ๆ ส่วนของโปรแกรมจะเห็นเหมือนกันหมด<br /> แต่ในกรณีที่เราต้องการให้เห็นเฉพาะในฟังก์ชั่นที่เราต้องการ เราสามารถกำหนดให้ตัวแปรเป็นตัวแปรท้องถิ่นได้ด้วยคำสั่ง <code>local</code><br /> เช่น</p> <pre>#!/bin/bash HELLO=Hello function hello { local HELLO=World echo $HELLO } echo $HELLO hello echo $HELLO</pre><p> สคริปต์นี้ตัวแปร <code>HELLO</code> ในโปรแกรมหลัก กับในฟังก์ชั่นจะเป็นตัวแปรคนละตัวกัน</p> </div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:41:03 +0000 wd 371 at https://www.thaitux.info https://www.thaitux.info/node/371#comments 4. การส่งต่อผลลัพธ์ หรือ ไปป์ (Pipes) https://www.thaitux.info/node/370 <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><h4>4.1 ความหมาย</h4> <p>ไปป์เป็นการส่งต่อผลลัพธ์จากคำสั่งหนึ่งไปเป็นค่านำเข้าของอีกคำสั่งหนึ่ง</p> <h4>4.2 ตัวอย่างไปป์</h4> <pre>$ <strong>ls -l | sed -e "s/[aeio]/u/g"</strong></pre><p>ตัวอย่างนี้จะนำเอาผลลัพธ์ที่ได้จากคำสั่ง <code>ls -l</code> ส่งต่อไปให้คำสั่ง <code>sed -e "s/[aeio]/u/g"</code><br /> ซึ่งจะแปลงการแสดงผลจากอักขระ a หรือ e หรือ i หรือ o ไปเป็นอักขระ u ทั้งหมด</p> <p>เราอาจเขียนคำสั่งเทียบเท่าได้ดังนี้</p> <pre>$ <strong>ls -l &gt; temp.txt</strong> $ <strong>sed -e "s/[aeio]/u/g" temp.txt</strong> $ <strong>rm temp.txt</strong></pre><p> จะเห็นว่าการทำไปป์ ลดขั้นตอนไปมาก คงเหลือเพียงบรรทัดเดียว</p> <h4>4.3 ตัวอย่างไปป์ที่สอง</h4> <pre>$ <strong>ls -l | grep "\.txt$"</strong></pre><p>ตัวอย่างนี้จะส่งผลลัพธ์จากคำสั่ง <code>ls -l</code> ต่อไปให้คำสั่ง <code>grep "\.txt$"</code> คือให้แสดงเฉพาะไฟล์ที่มีนามสกุลเป็น <code>.txt</code> เท่านั้น<br /> มีค่าเท่ากับคำสั่ง ls แบบใส่พารามิเตอร์กรอง</p> <pre>$ <strong>ls -l *.txt</strong></pre><p> <strong>หมายเหตุ</strong><br /> รูปแบบ <code>"\.txt$"</code> เป็นรูปแบบของ <a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/chap_04.html">Regular Expression</a> ซึ่งใช้มากในเชลล์สคริปต์ มีความหมายว่า "ที่ต้องลงท้ายด้วย .txt"</p> </div></div></div><div class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above"><div class="field-label">Topic:&nbsp;</div><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/96">bash</a></div><div class="field-item odd"><a href="/taxonomy/term/261">shell script</a></div></div></div> Wed, 21 Nov 2007 05:39:58 +0000 wd 370 at https://www.thaitux.info https://www.thaitux.info/node/370#comments