免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2456 | 回复: 8
打印 上一主题 下一主题

[学习共享] Notes for Advanced Bash-Scripting Version 10 (Latest) [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-07-31 06:33 |只看该作者 |倒序浏览
本帖最后由 houjun19830610 于 2014-07-31 06:40 编辑

2014/7/31

Part 1

1. We give the scripts executable permission via:

chmod u+rx <scriptname>

2. We name a bash script as scriptname.bash or scriptname.sh

3. To clean up logs, we can realize this function in three ways:

a. cat /dev/null > /var/log/messages
b. > /var/log/messages
c. echo " " > /var/log/messages

4. An enhanced and generalized version of bash script that is to clean up logs

=======================================================================================================
#!/bin/bash
# Clean up logs


LOG_DIR=/var/log          # That is the log folder
ROOT_UID=0                # Only user with $UID 0 has root privilege
LINES=50                      # Default number of lines saved
E_XCD=86                    # Can't change directory?
E_NOTROOT=87          # Non-root exit error


# Run as root
if [ "$UID" -ne "$ROOT_UID"  ]          # If current UID doesn't equal to 0 (Means the current user is not root)
then
     echo “Must be root to run the script.”     # Only root can run this script
     exit $E_NOTROOT    # Exit with specified signal
fi


if [ -n "$1" ]          # If the first parameter $1 is not empty, then execute "then" command.
then
     lines=$1          # The first parameter means the last lines you want to keep
else
     lines=$LINES          # Default lines you want to keep, if not specified on command-line
fi


cd $LOG_DIR || {
     echo "Can't change to necessary directory." 2> /dev/null     # If destination path doesn't exist, exit with specified signal
     exit $E_XCD;
}

tail -n $lines messages > mesg.tmp          # Save last section of messages log file
mv mesg.tmp messages                         # To keep as new log file

cat /dev/null  > wtmp          # Clean up logging information

exit 0          # A zero return means that the script is executed successfully
=======================================================================================================

5. If you want to execute a bash script, please test it by ./scriptname with user execution privilege.

6. Preliminary exercise:

A. Write a script that upon invocation shows the time and date, lists all logged-in users, and gives the system uptime. The script saves this information to a log file.

Answer:

#!/bin/bash

echo "Today is `/bin/date`.”      
echo "`/usr/bin/who | awk '{ print $1 }' | sort | uniq | xargs | tr " " ","` are logging.”     # Get root,alex result. As xargs can re-arrange the result delimited by blank, we can use "tr" command to replace the blank with comma.  And if we don't use "sort" command, "uniq" command doesn't make sense."uniq" command only works after the results get sorted.
  
if [ `uptime | awk '{ print $4 }' | cut -c1-3` == "min" ]     # If min parameter exists, the result is minute. Otherwise, it is day.
then
    echo "The system has run `/usr/bin/uptime | awk '{ print $3 }'` minutes."
else
    echo "The system has run `/usr/bin/uptime | awk '{ print $3 }'` days."
fi

7. In vi / vim editor, try "esc" button and ":nohl" to cancel highlight.

8. In /etc/vimrc, add "syntax on" to highlight syntax.

9. # is used for comments. Lines beginning with a # (with the exception of #!) are comments and will not be executed. One # will not end until you use a new line. That means if you want to use a new command, please don't use the same line as the line of comments.
But the standard quoting and escape characters (' \) escape the #. (" can't escape #)

#!/bin/bash
echo 'The # here doesn’t begin a comment.'
echo The \# here doesn’t begin a comment.

10. “;”semicolon, permits putting two or more commands on the same line.
echo "File $filename exists." ; cp $filename $filename.bak     # The first command runs and then the second runs accordingly.

“;”is also used for case option. (double semicolon)

#!/bin/bash

case  “$var” in
     abc) echo “\$var = abc” ;;
     xyz) echo “\var = xyz” ;;
esac

11. #!/bin/bash
if [ -x “$filename” ] ; then    # If $filename can be executed, the result is true. That means "then" command will be executed accordingly.

12. "dot" command is equivalent to source which is a bash builtin.

A. When working with filenames, a leading dot is the prefix of a "hidden" file, a file that an ls will not normally show. (ls -al can show.)

B. When considering directory names, a single dot represents the current wiring directory, and two dots denote the parent directory. The dot often appears as the destination directory of a file movement command (sometimes means current directory.)
For instance:
cp /home/alex/junk/* .     # Copy specified files to current directory ($PWD)

C. "dot" character matches a single character. This function is used in regular expression.

13. comma operator links together a series of arithmetic operations. All are evaluated, but only the last one is returned.
For example,
#!/bin/bash
let "t2 = ((a=9, 15/3))"
echo $t2
# Set "a=9" and "t2 = 15 / 3”

For another instance,
#!/bin/bash
for file in /{,usr/}bin/*calc
# Find all files ending in "calc" in /bin and /usr/bin directories.

14. escape [backslash] \ , a quoting mechanism for single characters.
\X escapes the character X. The \ may be used to quote "and ', so they are expressed literally.

15. / , filename path separator like /home/alex/projects. This is also the division arithmetic operator.

16. ` backquotes , the command in the backquotes will be executed firstly.
For instance,
echo `expr 4 + 5`

17. : , this symbol is named as null command [colon], equivalent of a "NOP"(no op, do-nothing operation). It is considered as "true". Itself is a bash builtin and its exit status is true (0)
#!/bin/bash
:
echo $? # This is to get the exit status of last command. If the last command runs successfully, the result is 0. Otherwise, the result will be from 1 to 255.

Another example:
#!/bin/bash

while :
do
        echo $PWD
done

# Same as
#       while true
#       do
#               echo $PWD
#       done

论坛徽章:
1
处女座
日期:2014-01-21 13:20:51
2 [报告]
发表于 2014-07-31 07:59 |只看该作者

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
3 [报告]
发表于 2014-07-31 08:44 |只看该作者
chmod u+rx <scriptname>
为何要指明加上 r 呢?

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
4 [报告]
发表于 2014-07-31 08:48 |只看该作者
if [ -n "$1" ]          # If the first parameter $1 is not empty, then execute "then" command.
这里可以考虑增加一个合法性判断,因为用户输入的 $1 不一定是数字。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2014-07-31 10:24 |只看该作者
回复 3# Shell_HAT


    光有x没有r,也不可以执行

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2014-07-31 10:24 |只看该作者
回复 4# Shell_HAT


    这个有道理,可用case语句。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
7 [报告]
发表于 2014-08-04 22:22 |只看该作者
2014/8/4

19. #!/bin/bash

VAR=2

if [ $VAR = 1 ]
then :     # Do nothing and branch ahead.
else
        echo "Test failed."
fi

20. #!/bin/bash

: > /tmp/test     # Empty /tmp/test file. However, this doesn’t fork a new process as “:” is a builtin.

21. Sometimes “:” serves as a field separator, like in /etc/passwd and in the $PATH variable.
[root@test scripts]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/var/cfengine/bin:/root/bin

22. “!” [reverse or negate]
“!=“ means not equal

23. “*” [asterisk] serves a “wild card” for filename expansion in globbing. By itself, it matches every filename in a given directory.
[root@test scripts]# echo *
checkups test
Also, it represents any number (zero) characters in a regular expression.

24. A double asterisk serves as arithmetic operator to represent exponent operator or extended file-match blobbing.

25. “?” serves as test operator
#!/bin/bash

(( var0 = var1<98?9:21 ))

If var1 is less than 98, then var0 equals to 9.
If var1 is great or equals 98, then var0 equals to 21.

26. “?” serves as wild card, as a single-character for filename expansion in globbing as well as extended regular expression.

27. “$” serves as variable substitution
var1=5
var2=23abc

echo $var1     # 5
echo $var2     # 23abc

28. “$” serves end-of-line in regular expression, meaning the end of a line in test.

28. “${}” serves as parameter substitution.

29. “$'…'” This construct expands single or multiple escaped octal or hex values in to ASCII or Unicode characters.

30. “$*,$@,$#,$0,$?”
$@ = $*
They show all of the parameters. The parameters are in their original positions.

[root@test scripts]# cat test
#!/bin/bash

for var in $*
do
echo $var
done
[root@test scripts]# ./test 1 2 3
1
2
3

[root@test scripts]# cat test
#!/bin/bash

for var in $@
do
echo $var
done
[root@test scripts]# ./test 1 2 3
1
2
3

For “$*”, the results are like “$1 $2 $3”
[root@test scripts]# cat test
#!/bin/bash

for var in "$*"
do
echo $var
done
[root@test scripts]# ./test 1 2 3
1 2 3

For “$@“, the results are like “$1" "$2" "$3" "$4”
[root@test scripts]# cat test
#!/bin/bash

for var in "$@"
do
echo $var
done
[root@test scripts]# ./test 1 2 "3 4"
1
2
3 4

$0 means bash file name.

$? the exit status of last command.

31. $$ holds the process ID of the script in which it appears.

32. () command group, it starts a subshell. The parent process, the script, can’t read variables created in the child process, the subshell.
A comma may act upon a comma-separated list of file specs within braces. No spaces allowed within the braces unless the spaces are quoted or escaped.
echo {file1,file2}\ :{\ A,” B”,’ C’}
file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C

33. echo {a..c}     # a b c
    echo {1..3}     # 1 2 3

34. {} means block of code.
function echovar
{
echo $var1
echo $var2
}

echovar

35. For example 1
[root@test scripts]# vim test

#!/bin/bash
SUCCESS=0
E_NOARGS=65

if [ -z "$1" ]          # If "$1" is empty
then
        echo "Usage: `basename $0` rpm-file”     # Get the full script name, no need path.
        exit $E_NOARGS
fi

{
echo
echo "Archive Description:"
rpm -qpi $1    # Query description.
echo
echo "Archive Listing:"
rpm -qpl $1    # Query Listing.
echo
rpm -i --test $1        # Query whether rpm file can be installed.
if [ "$?" -eq $SUCCESS ]
then
        echo "$1 can be installed."
else
        echo "$1 can't be installed."
fi
echo    # End code block.
}  > "$1.test"  # Redirects output of everything in block to file.

echo "Results of rpm test in file $1.test"

exit 0

36. {}\; mostly used in find constructs but not a shell builtin.
find /var/log -name messages -exec tail -100 '{}' \;

37.[] test.
[[]] test. Used more flexible.

38.[] array element.
Array[1]]slot_1
echo ${Array[1]}

39. $[…] integer expansion.
a=3
b=7

echo $[$a+$b]     # 10
echo $[$a*$b]     # 21

40. (()) integer expansion.
equals to $[…]

41.
script > filename      # Redirects the output of script to the file filename. overwrite if it already exists.
command &> filename     # Redirects both the stdout and stderr of command to filename.
command &> /dev/null     # Redirects stdout and stderr to black hole.
command >&2     # Redirects stdout of command to stderr.
script >> filename     # Appends the output of script to filename. If filename doesn’t exist, it is created.

42. [i]<>filename     # Opens filename for reading and writing and assigns file descriptor i to it. If filename doesn’t exist, it is created.
exec 3<> filename     # Give file descriptor to filename. If filename doesn’t exist, it is created.
read -n 4 <&3     # Open file descriptor and read the first four characters.
echo -n . >&3     # Replace the fifth character with .
exec 3>&-     # Close file desciptior

43. \<, \>  word boundary
[root@test scripts]# cat test
the
I am the hero
atheb

[root@test scripts]# grep "\<the\>" test
the
I am the hero

44. “|” pipe passes the output (stdout) of a previous command to the input (stdin) of the next one, or to the shell. Pipe runs a child process, and therefore can’t alter script variables.

45. “||”
cd /tmp/test || echo “Test failed”     # If cd /tmp/test failed, then echo Test failed.

46. “&” run job in background.
[root@test scripts]# sleep 10 &
[1] 27820

47. “&&” AND logical operator. If the first command runs ok, then the next command will be executed.
cd /tmp/test && echo “Test ok.”

48. cat - >> test
If you use the above command, you can input some characters and then input ctrl+d to end the command. File test will contain the inputs.

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
8 [报告]
发表于 2014-08-04 22:46 |只看该作者
看到这一大堆就没兴趣~

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2014-08-05 08:07 |只看该作者
回复 8# yestreenstars


    学习呗,不喜欢可以不看 :)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP