Bash Scripting Learn Notes
References:
[1] http://www.tldp.org/LDP/Bash-Beginners-Guide/html/
1. Executing programs from a script
When the program being executed is a shell script, bash will create a new bash process using a fork. This subshell reads the lines from the shell script one line at a time. Commands on each line are read, interpreted and executed as if they would have come directly from the keyboard.
While the subshell processes each line of the script, the parent shell waits for its child process to finish. When there are no more lines in the shell script to read, the subshell terminates. The parent shell awakes and displays a new prompt.
If input is not commented, the shell reads it and divides it into words and operators, employing quoting rules to define the meaning of each character of input. Then these words and operators are translated into commands and other constructs, which return an exit status available for inspection or processing. The above fork-and-exec scheme is only applied after the shell has analyzed input in the following way:
The shell reads its input from a file, from a string or from the user's terminal.
Input is broken up into words and operators, obeying the quoting rules, see Chapter 3. These tokens are separated by metacharacters. Alias expansion is performed.
The shell parses (analyzes and substitutes) the tokens into simple and compound commands.
Bash performs various shell expansions, breaking the expanded tokens into lists of filenames and commands and arguments.
Redirection is performed if necessary, redirection operators and their operands are removed from the argument list.
Commands are executed.
Optionally the shell waits for the command to complete and collects its exit status.
It is preferred to execute the script like this in a subshell. The variables, functions and aliases created in this subshell are only known to the particular bash session of that subshell. When that shell exits and the parent regains control, everything is cleaned up and all changes to the state of the shell made by the script, are forgotten. If you don't want to start a new shell but execute the script in the current shell, you source it: source script_name.sh
2. Debug the script
set -x # activate debugging from here |
3. Introduction of some configuration files
1) /etc/profile
When invoked interactively with the --login option or when invoked as sh, Bash reads the /etc/profile instructions. These usually set the shell variables PATH, USER, MAIL, HOSTNAME and HISTSIZE.
2) /etc/bashrc
You might also find that /etc/profile on your system only holds shell environment and program startup settings, while /etc/bashrc contains system-wide definitions for shell functions and aliases. The /etc/bashrc file might be referred to in /etc/profile or in individual user shell initialization files.
3) ~/.bash_profile
This is the preferred configuration file for configuring user environments individually. In this file, users can add extra configuration options or change default settings:
4) ~/.bash_login
This file contains specific settings that are normally only executed when you log in to the system.
5) ~/.profile
In the absence of ~/.bash_profile and ~/.bash_login, ~/.profile is read. It can hold the same configurations, which are then also accessible by other shells. Mind that other shells might not understand the Bash syntax.
6) ~/.bashrc
Today, it is more common to use a non-login shell, for instance when logged in graphically using X terminal windows. Upon opening such a window, the user does not have to provide a user name or password; no authentication is done. Bash searches for ~/.bashrc when this happens, so it is referred to in the files read upon login as well, which means you don't have to enter the same settings in multiple files.
7) ~/.bash_logout
This file contains specific instructions for the logout procedure.
When making changes to any of the above files, users have to either reconnect to the system or source the altered file for the changes to take effect.
4. Special Bash Variables
Character | Definition |
---|---|
$* | Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable. |
$@ | Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. |
$# | Expands to the number of positional parameters in decimal. |
$? | Expands to the exit status of the most recently executed foreground pipeline. |
$- | A hyphen expands to the current option flags as specified upon invocation, by the set built-in command, or those set by the shell itself (such as the -i). |
$$ | Expands to the process ID of the shell. |
$! | Expands to the process ID of the most recently executed background (asynchronous) command. |
$0 | Expands to the name of the shell or shell script. |
$_ | The underscore variable is set at shell startup and contains the absolute file name of the shell or script being executed as passed in the argument list. Subsequently, it expands to the last argument to the previous command, after expansion. It is also set to the full pathname of each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file. |
The positional parameters are the words following the name of a shell script. They are put into the variables $1, $2, $3 and so on. As long as needed, variables are added to an internal array. $# holds the total number of parameters. The implementation of "$*" has always been a problem and realistically should have been replaced with the behavior of "$@". In almost every case where coders use "$*", they mean "$@". "$*" Can cause bugs and even security holes in your software. e.g. User franky starts entering the grep command, which results in the assignment of the _ variable. The process ID of his shell is 10662. After putting a job in the background, the ! holds the process ID of the backgrounded job. The shell running is bash. When a mistake is made, ? holds an exit code different from 0 (zero).
$* 这个程式的所有参数
$# 这个程式的参数个数
$@ 跟$*类似,但是可以当作数组用
5. Single quotes and double quotes
franky ~> echo '$date' |
franky ~> echo "$date" |
6. Basic Substitutions
* Shell parameter and variable expansion
${Parameter} e.g. echo ${USER:=chi}
* Command Substitution
$(Command) or `Command` e.g. echo "$(date)" or echo `date`
* Arithmetic expansion
$((Expression)) e.g. echo "$((3*2))" or echo "$((2 == 2 ? 1 : 0))"
* Process Substitution
<(LIST) or >(LIST) e.g. ls -l /proc/self/fd > /var/tmp/fdtest.at
* $[ EXPRESSION ]
However, this will only calculate the result of EXPRESSION, and do no tests:
franky ~> echo $[365*24] |
7. String Comparisons
An example of comparing strings for testing the user ID:
if [ "$(whoami)" != 'root' ]; then |
With Bash, you can shorten this type of construct. The compact equivalent of the above test is as follows:
[ "$(whoami)" != 'root' ] && ( echo you are using a non-privileged account; exit 1 ) |
Similar to the "&&" expression which indicates what to do if the test proves true, "||" specifies what to do if the test is false.
Regular expressions may also be used in comparisons:
anny > gender="female" anny > if [[ "$gender" == f* ]] |
8. [] vs [[]]
Contrary to [, [[ prevents word splitting of variable values. So, if VAR="var with spaces", you do not need to double quote $VAR in a test - eventhough using quotes remains a good habit. Also, [[ prevents pathname expansion, so literal strings with wildcards do not try to expand to filenames. Using [[, == and != interpret strings to the right as shell glob patterns to be matched against the value to the left, for instance: [[ "value" == val* ]].
#!/bin/bash # This script gives information about a file. FILENAME="$1" echo "Properties for $FILENAME:" if [ -f $FILENAME ]; then |
The above example will fail if the value of $1 can be parsed as multiple words. In that case, the if command can be fixed either using double quotes around the filename, or by using [[ instead of [.
()会开启一个新的子shell,{}不会开启一个新的子shell
(())常用于算术运算比较,[[]]常用于字符串的比较.
$()返回括号中命令执行的结果
$(())返回的结果是括号中表达式值
${ }参数替换与扩展
9. echo
The echo built-in command outputs its arguments, separated by spaces and terminated with a newline character. The return status is always zero. echo takes a couple of options:
-e: interprets backslash-escaped characters.
-n: suppresses the trailing newline.
echo -e "Feeding $menu to $animal...\n"
10. > /dev/null/ 2>&1
>
is for redirect
/dev/null
is a black hole where any data sent, will be discarded
2
is the file descriptor for Standard Error
>
is for redirect
&
is the symbol for file descriptor (without it, the following 1
would be considered a filename)
1
is the file descriptor for Standard Out
Therefore >/dev/null 2>&1
is redirect the output of your program to /dev/null
. Include both the Standard Error
and Standard Out
.
Much more information is available at The Linux Documentation Project's I/O Redirection page.
cron
will only email you if there is some output from you job. With everything redirected to null
, there is no output and hence cron
will not email you.
11. Array
[bob in ~] ARRAY=(one two three) [bob in ~] echo ${ARRAY[*]} |
[bob in ~] unset ARRAY[1] [bob in ~] echo ${ARRAY[*]} |
[bob in ~] echo $SHELL |
12. Substitution and String
${VAR:-WORD}
If VAR is not defined or null, the expansion of WORD is substituted; otherwise the value of VAR is substituted:
[bob in ~] echo ${TEST:-test} |
This form is often used in conditional tests, for instance in this one:
[ -z "${COLUMNS:-}" ] && COLUMNS=80 |
If the hyphen (-) is replaced with the equal sign (=), the value is assigned to the parameter if it does not exist:
[bob in ~] echo $TEST2 [bob in ~] echo ${TEST2:=$TEST} |
To strip a number of characters, equal to OFFSET, from a variable, use this syntax:
${VAR:OFFSET:LENGTH}
The LENGTH parameter defines how many characters to keep, starting from the first character after the offset point. If LENGTH is omitted, the remainder of the variable content is taken:
[bob in ~] export STRING="thisisaverylongname" [bob in ~] echo ${STRING:4} |
13. Functions
Special built-in commands are found before shell functions during command lookup. The special built-ins are: break, :, ., continue, eval, exec, exit, export,readonly, return, set, shift, trap and unset.
[lydia@cointreau ~/test] cat showparams.sh
#!/bin/bash echo "This script demonstrates function arguments."
echo echo "Positional parameter 1 for the script is $1."
echo test ()
{
echo "Positional parameter 1 in the function is $1."
RETURN_VALUE=$?
echo "The exit code of this function is $RETURN_VALUE."
} test other_param [lydia@cointreau ~/test] ./showparams.sh parameter1
This script demonstrates function arguments. Positional parameter 1 for the script is parameter1. Positional parameter 1 in the function is other_param.
The exit code of this function is 0. [lydia@cointreau ~/test]
14. Signals
Standard key combination | Meaning |
---|---|
Ctrl+C | The interrupt signal, sends SIGINT to the job running in the foreground. |
Ctrl+Y | The delayed suspend character. Causes a running process to be stopped when it attempts to read input from the terminal. Control is returned to the shell, the user can foreground, background or kill the process. Delayed suspend is only available on operating systems supporting this feature. |
Ctrl+Z | The suspend signal, sends a SIGTSTP to a running program, thus stopping it and returning control to the shell. |
Both kill commands send the TERM signal if none is given.
When killing a process or series of processes, it is common sense to start trying with the least dangerous signal, SIGTERM. That way, programs that care about an orderly shutdown get the chance to follow the procedures that they have been designed to execute when getting the SIGTERM signal, such as cleaning up and closing open files. If you send a SIGKILL to a process, you remove any chance for the process to do a tidy cleanup and shutdown, which might have unfortunate consequences.
But if a clean termination does not work, the INT orKILL signals might be the only way. For instance, when a process does not die using Ctrl+C, it is best to use thekill -9 on that process ID.
Signal name | Signal value | Effect |
---|---|---|
SIGHUP | 1 | Hangup |
SIGINT | 2 | Interrupt from keyboard |
SIGKILL | 9 | Kill signal |
SIGTERM | 15 | Termination signal |
SIGSTOP | 17,19,23 | Stop the process |
15. Traps
trap [COMMANDS] [SIGNALS]
This instructs the trap command to catch the listed SIGNALS, which may be signal names with or without the SIG prefix, or signal numbers. If a signal is 0 or EXIT, the COMMANDS are executed when the shell exits. If one of the signals is DEBUG, the list of COMMANDS is executed after every simple command. A signal may also be specified as ERR; in that case COMMANDS are executed each time a simple command exits with a non-zero status. Note that these commands will not be executed when the non-zero exit status comes from part of an if statement, or from a while or until loop. Neither will they be executed if a logical AND (&&) or OR (||) result in a non-zero exit code, or when a command's return status is inverted using the ! operator.
#!/bin/bash |
Special built-in commands are found before shell functions during command lookup. The special built-ins are: break, :, ., continue, eval, exec, exit, export,readonly, return, set, shift, trap and unset.
16. System environment variables
Environment variables set without export
will not be inherited in the environment of the commands you are calling. e.g.
HOSTNAME is the environment variable and could be got by $HOSTNAME. But it couldn't be accessed by java -jar example.jar.
1) export HOSTNAME=$HOSTNAME and then you could access it by System.getenv("HOSTNAME").
2) java -DHOSTNAME='XXX' -jar example.jar
17. About other people
- w --- tells you who's logged in, and what they're doing. Especially useful: the 'idle' part. This allows you to see whether they're actually sitting there typing away at their keyboards right at the moment.
- who --- tells you who's logged on, and where they're coming from. Useful if you're looking for someone who's actually physically in the same building as you, or in some other particular location.
- finger username --- gives you lots of information about that user, e.g. when they last read their mail and whether they're logged in. Often people put other practical information, such as phone numbers and addresses, in a file called .plan. This information is also displayed by 'finger'.
- last -1 username --- tells you when the user last logged on and off and from where. Without any options, last will give you a list of everyone's logins.
- talk username --- lets you have a (typed) conversation with another user
- write username --- lets you exchange one-line messages with another user
- elm --- lets you send e-mail messages to people around the world (and, of course, read them). It's not the only mailer you can use, but the one we recommend. See the elm page, and find out about the departmental mailing lists (which you can also find in /user/linguistics/helpfile).
Bash Scripting Learn Notes的更多相关文章
- Linux Academy Learn Notes
Linux Essentials Certification Globbing ls ?.txt --- ? stands for one character while * means one or ...
- Conditions in bash scripting (if statements)
Shell中判断语句if中-z至-d的意思 - sunny_2015 - 博客园 https://www.cnblogs.com/coffy/p/5748292.html Conditions in ...
- 高级Bash Scripting系列笔记--01之“什么情况不适用Bash Script”
1. 占用资源的任务,尤其那些影响速度的工作 比如排序,哈希,递归等等. 2. 大量使用数学运算 尤其是浮点运算,比如任意精度的计算或者复数计算等等,这类使用C++会好很多. 3. 跨平台的(适用 ...
- Java 8 Learn Notes
Main reference: [1] http://winterbe.com/posts/2014/03/16/java-8-tutorial/ [2] https://plus.google.co ...
- 『BASH』——Learn BashScript from Daniel Robbins——[003]
ABSTRACT: Daniel Robbins is best known as the creator of Gentoo Linux and author of many IBM develop ...
- 『BASH』——Learn BashScript from Daniel Robbins——[001-002]
ABSTRACT: Daniel Robbins is best known as the creator of Gentoo Linux and author of many IBM develop ...
- Java 8 Learn Notes - Streams
Main reference [1] http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples 1. How Stream ...
- R Language Learn Notes
One #install package install.packages("ggplot2") #load library library(ggplot2) #update.pa ...
- Dart Learn Notes 04
流程控制语句 流程控制语句的作用就是控制代码的执行流程. if and else var a = 10; if(a > 10){ print('ok'); }else if( 5 < a ...
随机推荐
- POPTEST老李分享session,cookie的安全性以及区别 1
POPTEST老李分享session,cookie的安全性以及区别 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程 ...
- 老李推荐:第2章4节《MonkeyRunner源码剖析》了解你的测试对象: NotePad窗口Activity之菜单简介
老李推荐:第2章4节<MonkeyRunner源码剖析>了解你的测试对象: NotePad窗口Activity之菜单简介 NotePad窗口Activity之菜单简介 这里我们总共用到 ...
- dotnet Core 调用HTTP接口,系统大量CLOSE_WAIT连接问题的分析,尚未解决。
环境: dotnet core 1.0.1 CentOS 7.2 今天在服务器巡检的时候,发现一个服务大量抛出异常 异常信息为: LockStatusPushError&&Messag ...
- 用pl/sql游标实现约瑟夫环
什么是约瑟夫环: 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为1的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数, ...
- JavaScript基础学习(四)—Object
一.Object的基本操作 1.对象的创建 在JavaScript中,创建对象的方式有两种:构造函数和对象字面量. (1)构造函数 var person = new Object( ...
- MAT(Memory Analyzer Tool)使用心得
起因:最近在跟踪产品的性能问题,期间主要问题体现在JVM的内存回收问题,使用MAT工具进行JVM内存分析(也可对android 的应用内存分析) 问题描述: 1.部分后端服务在运行一段时间后会突然年老 ...
- DataTable源码分析(二)
DataTable源码分析(二) ===================== DataTable函数分析 ---------------- DataTable作为整个插件的入口,完成了整个表格的数据初 ...
- MySQL读写分离技术
1.简介 当今MySQL使用相当广泛,随着用户的增多以及数据量的增大,高并发随之而来.然而我们有很多办法可以缓解数据库的压力.分布式数据库.负载均衡.读写分离.增加缓存服务器等等.这里我们将采用读写分 ...
- 由if-else,switch代替方案引起的思考
关键词:条件判断,多态,策略模式,哈希表,字典map 笔者在用python实现事件驱动后,发现python是没有提供switch语句,python官方推荐多用字典来代替switch来实现,这让我就觉得 ...
- oracle分区表的建立方法(包含已经存在的表要分区)分享,非常好
非原创 Oracle提供了分区技术以支持VLDB(Very Large DataBase).分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中.分区完全对应用透明. Oracle的分区表可 ...