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 ...
随机推荐
- Oracle dual表的用途
dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录.我们可以用它来做很多事情,如下: 1.查看当前用户,可以在 SQL Plus中执行下面语句 sele ...
- IC卡读卡器web开发,支持IE,Chrome,Firefox,Safari,Opera等主流浏览 器
IC卡读卡器在web端的应用越来越多,但是早期发布的ocx技术只支持IE浏览器,使用受到了很多的限制.IC卡读卡器云服务的推 出,彻底解决了以上的局限,使得IC卡读卡器不仅可以应用在IE浏览器上,还可 ...
- [编织消息框架][JAVA核心技术]动态代理应用10-水平扩展方案
服务分为系统服务同用户服务两种 水平扩展是基于系统服务,而拆分方式又有几种方案,按数据跟业务情况来做决策 1.每个服务独立存储(图1):每个服务只负责一个或多个领域实体存储,A服务不能直接修改B服务的 ...
- 浩哥解析MyBatis源码(十)——Type类型模块之类型处理器
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6715063.html 1.回顾 之前的两篇分别解析了类型别名注册器和类型处理器注册器,此二 ...
- Vuex(一)——vuejs的状态管理模式
一.Vuex是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式. 它采用集中式存储 管理 应用的所有组件 的 状态,并以 相应的规则 保证 状态以一种 可预测的方式 发生变化. ...
- 修改nagios密码和遇到的问题
htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin 密码 密码 service httpd restart 由于本屌丢掉一个s使/ ...
- 架构设计之Spring-Session分布式集群会话管理
前言 通常在web开发中,回话管理是很重要的一部分,用于存储与用户相关的一些数据.对于JAVA开发者来说,项目中的session一般由Tomcat或者jetty容器来管理. 特点介绍 尽管使用特定的容 ...
- xml语法规则
所有 XML 元素都须有关闭标签 在 HTML,经常会看到没有关闭标签的元素: <p>This is a paragraph <p>This is another paragr ...
- Angular2快速起步——构建一个简单的应用
构建此应用,分为如下几步: 1.环境准备:安装Node.js和npm: 2.创建并配置此项目: 3.创建应用: 4.创建组件并添加到应用程序中: 5.启动应用程序: 6.定义作为该应用的宿主页面: 7 ...
- 关于System.Windows.Forms.DateTimePicker的一个Bug
几天接到客户的反馈,说系统无法查询2017年2月份的账单,原因是没办法选择2017年2月份,没办法选择2月份???,马上开启vs,运行系统,应为市去年的系统,测试数据也是去年的,就查询了2016年2月 ...