当前位置: 首页 > 工具软件 > bash-handbook > 使用案例 >

bash shell总结

姜杜吟
2023-12-01

标准

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02
https://www.gnu.org/software/bash/

简介

就是Linux系统的一个外部接口,外壳。
Bash is the GNU Project’s shell—the Bourne Again SHell. This is an sh-compatible shell that incorporates useful features from the Korn shell (ksh) and the C shell (csh). It is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. It offers functional improvements over sh for both programming and interactive use. In addition, most sh scripts can be run by Bash without modification.

shell的一大缺点

使用shell的一个缺点是性能。频繁的调用工具集软件,会导致频繁的文件读取,进程clone,信号处理等等。
导致性能上的损耗。

set -x

这个的意识是将脚本的命令,表达式执行都打印到 stderr;
也就是如果想将这个调试信息打印到文件,需要使用 2><file_name>

各种括号的用法

https://www.runoob.com/w3cnote/linux-shell-brackets-features.html

错误 unary operator expected

这个提示的含义是:需要一个单操作数;但是从脚本的意思还是想通过比较变量是否是 “yes"。
is_virtual1=“”
if [ ${is_virtual1} == “yes” ];
then
echo “abc”
fi

a.sh: line 6: [: ==: unary operator expected

分析

bash a.sh

  • is_virtual1=
  • ‘[’ == yes ‘]’
    a.sh: line 6: [: ==: unary operator expected
    这里看到,最终的比较表达式混乱了。

解决方法

https://stackoverflow.com/questions/13617843/unary-operator-expected-error-in-bash-if-condition

  1. 使用双中括号
  2. 将变量${is_virtual1},用双引号括起来

not found 错误

如果脚本内容看着没有问题,但是运行的时候,却提示文件没找到,可能的原因是 windows 环境下的字符问题。
使用dos2unix 进行转换脚本文件。或者使用:cat add_ip.sh | tr -d “\r” > add_ip1.sh
https://stackoverflow.com/questions/2637936/ksh-shell-script-wont-execute-and-returns-127-not-found

-

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/systemtap_beginners_guide/using-usage
You can also instruct stap to run scripts from standard input using the switch -. To illustrate:
Example 2.1. Running Scripts From Standard Input
echo “probe timer.s(1) {exit()}” | stap -

– A – signals the end of options and disables further option processing. Any arguments after the –
are treated as filenames and arguments. An argument of - is equivalent to --.
命令里如果单独出现两个 --, 代表 这个命令的 参数部分已经结束。

怎么判断使用的是bash

可以看 /etc/passwd下的设置
或者通过ps 命令查看 ssh 调用的最终的是哪一个shell

<< !

有时候打印使用说明时,会使用下面这种方式,重定向输出到cat,使用 两个! 号作为分割符(可以是任意的字符)

cat << !
	${script}: [ -c|-h ] -p <diskpath>
	${script}: [ -c|-h ] -d <daemon>
	!

时间相关的参数

TMOUT

If set to a value greater than zero, TMOUT is treated as the default timeout for the read builtin. The select command terminates if input does not arrive after TMOUT seconds when input is coming from a terminal. In an interactive shell, the value is interpreted as the number of seconds to wait for a line of input after issuing the primary prompt. Bash terminates after waiting for that number of seconds if a complete line of input does not arrive.

遇到的错误

restricted: cannot specify `/’ in command names

set -r 之后就出现这个错误;

[root@rhel-cleanmodules ~]# set -r
[root@rhel-cleanmodules ~]# set -ra
[root@rhel-cleanmodules ~]# which set
-bash: /usr/bin/which: restricted: cannot specify `/' in command names
[root@rhel-cleanmodules ~]#
[root@rhel-cleanmodules ~]# which set
-bash: /usr/bin/which: restricted: cannot specify `/' in command names
[root@rhel-cleanmodules ~]# man set
[root@rhel-cleanmodules ~]# which bash
-bash: /usr/bin/which: restricted: cannot specify `/' in command names

认识误区

返回值应用

4973 rc=$?
4974 if (( ${rc} != 0 )) && (( ${rc} != 1 ))///例子这好个是
4975 then

4974 if (( ${?} != 0 )) && (( ${?} != 1 )) //这里的第二个条件, $?已经发生改变。
4975 then

括号为什么使用空格分开

The braces are reserved words, so they must be separated from the list by blanks or other shell metacharacters. The parentheses are
operators, and are recognized as separate tokens by the shell even if they are not separated
from the list by whitespace.

使用

type 关键字

验证当前的变量函数是否存在
type [-aftpP] name [name …]
With no options, indicate how each name would be interpreted if used as a command name. If the -t option is used, type prints a string which is one of alias, keyword, function, builtin, or file if name is an alias, shell reserved word, function, builtin, or disk file, respectively. If the name is not found, then nothing is printed, and an exit status of false is returned. If the -p option is used, type either returns the name of the disk file that would be executed if name were specified as a command name, or nothing if type -t name would not return file. The -P option forces a PATH search for each name, even if type -t name would not return file. If a command is hashed, -p and -P print the hashed value, which is not necessarily the file that appears first in PATH. If the -a option is used, type prints all of the places that contain an executable named name. This includes aliases and functions, if and only if the -p option is not also used. The table of hashed commands is not consulted when using -a. The -f option suppresses shell function lookup, as with the command builtin. type returns true if all of the arguments are found, false if any are not found.
type func &>/dev/null
if (( $? != 0 )); then

变量

数组

name=(“Linux Handbook” “It’s FOSS”)
echo “Hello ${name[1]}!”

中划线

${parameter:-word} uses word as the default if the parameter is unset.
https://stackoverflow.com/questions/40230008/whats-the-usages-of-hyphen-in-linux-shell

+

${variable:+string}如果variable有值,就用string,和减号相反。

变量长度

${#variable}

大小写转换

#Capitalizes
${variable^}
${variable^^}

#Lowercases
${variable,}
${variable,}

管道

If ‘|&’ is used, command1’s standard error, in addition to its standard output, is connected to command2’s standard input through the pipe; it is shorthand for 2>&1 |. This implicit redirection of the standard error to the standard output is performed after any redirections specified by the command.

后台运行

If a command is terminated by the control operator ‘&’, the shell executes the command asynchronously in a subshell.

~

The character ‘~’ at the beginning of a file name also has special significance. If alone, or followed by a slash, it represents your home directory. For example ~/bin expands to /home/you/bin. If the ‘~’ is followed by a word, the string represents the home directory of the user named by that word. For example ~john/bin expands to /home/john/bin.

?*

表示所有的参数。

星号与正则表达式的区别

在shell里,星号匹配任意字符;正则表达式里表示个数,之前表达式匹配的个数,可以用来匹配零个或者多个星号之前的字符表达式。You may be familiar with * as a shell metacharacter, where it means “zero or more characters.”
但是shell里的星号和正则表达式里的含义完全不一样。
举例;匹配字符串:

        # Update PATH
        if [[ ${PATH} != *${tmp_upd_sbin_dir}* ]]; then
                export PATH=${tmp_upd_sbin_dir}:${PATH}
        fi

重定向

The “>” redirection operator truncates the file before the shell does anything else;重新生成文件

是append,续接

eval

eval [arg …]
The args are read and concatenated together into a single command. This command is then read and executed by the shell, and its exit status is returned as the value of eval. If there are no args, or only null arguments, eval returns 0.
eval 返回命令执行的返回值。

set 命令

重新设置参数。
set [–abefhkmnptuvxBCEHPT] [-o option-name] [arg …]
set [+abefhkmnptuvxBCEHPT] [+o option-name] [arg …]
Without options, the name and value of each shell variable are displayed in a format that can be reused as input for setting or
resetting the currently-set variables. Read-only variables cannot be reset. In posix mode, only shell variables are listed. The
output is sorted according to the current locale. When options are specified, they set or unset shell attributes. Any arguments
remaining after option processing are treated as values for the positional parameters and are assigned, in order, to $1, $2, …
$n. Options, if specified, have the following meanings:
-a Automatically mark variables and functions which are modified or created for export to the environment of subsequent cmmands.
-b Report the status of terminated background jobs immediately, rather than before the next primary prompt. This is effective
only when job control is enabled.

<lc-a:root>/root:
# set a=b c d
<lc-a:root>/root:
# echo $1
a=b
<lc-a:root>/root:
# echo $2
c

{!}

   !      Expands  to the process ID of the job most recently placed into the background, whether executed as an asynchronous command or using the bg builtin (see JOB CONTROL below).

{0##*/}

0是命令行的第一个参数,也就是执行的命令,获取命令里的文件名,不带路径信息
相对的有 ${0%/*},这个是获取命令的路径;
例子:

<a:root>/root:
# cat a.sh
#!/bin/ksh
echo ${0##*/}
echo ${0%/*}
<a:root>/root:
# ./a.sh
a.sh
.   ### ${0%/*}
<a:root>/root:
# /root/a.sh
a.sh
/root   #### ${0%/*}

%% 删除末尾匹配的字符串

${parameter%%word}
${parameter%word}
${parameter%%word}
Remove matching suffix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the %'' case) or the longest matching pattern (the %%‘’ case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

获取硬盘分区的uuid

blkid -s UUID -o value

判断创建目录是否成功

if ! mkdir -p /tmp/abc /tmp/cde/ /tmp/sdf
then
fi

切换用户组

newgrp
newgrp - log in to a new group

反转字符串

[root@rhel-cleanmodules sbc]# man rev
[root@rhel-cleanmodules sbc]# echo “abced” |rev
decba

字串判断

		if [[ ${filename} == *"abc"* ]]; then
			continue;
		fi

反转文件行

[root@rhel-cleanmodules sbc]# which tac
/usr/bin/tac
[root@rhel-cleanmodules sbc]# rpm -qf /usr/bin/tac
coreutils-8.30-8.el8.x86_64

chmod 777 -R *

迭代修改权限

echo 不换行

echo “abc\c”, 末尾加\c

获取目录

<-a:root>/root:
/usr/bin/dirname
<-a:root>/root:
:rpm -qf /usr/bin/dirname
coreutils-8.30-8.el8.x86_64

上次命令的执行结果;

!$ ---- 上次命令的执行结果;

man 2 read, 找到 read的帮助文档在第二部分; 系统调用
man 1 read, 1 for the command. 第一部分是关于命令
1 Executable programs or shell commands
2 System calls (functions provided by the kernel)
3 Library calls (functions within program libraries)
4 Special files (usually found in /dev)
5 File formats and conventions eg /etc/passwd
6 Games
7 Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)
8 System administration commands (usually only for root)
9 Kernel routines [Non standard]

dmesg: print or control the kernel ring buffer, 只是查看内存中缓存的log,如果缓存被覆盖之后,就看不到了。所以我们可以根据有没有启动参数command 行来确定dmesg是否有丢的情况。

ps 命令,就是读取/proc目录下的内容

free
[root@localhost grub2]# free
total used free shared buff/cache available
Mem: 1873316 176708 1313896 8636 382712 1542800
Swap: 2170876 0 2170876 ///交互分区,是在硬盘上分配的空间,给kernel使用,当内存不够用时,可以将一部分内存放到磁盘交互分区上去。 一般情况下这个swap的使用情况应该时0,如果被使用很多的话说明系统需要做一下优化。

strace date |& grep read
That’s because strace prints it’s output on standard error and the pipe symbol is only grabbing standard out.
But in bash if you do |&, right next to each other. Then shell will arrange for both standard output and standard error to go into pipe.

cd 这个命令有点特殊,系统里没有binary与之对应;这个不是正规的Linux 命令,一般的命令会启动一个process来完成相应的认为,而cd的作用是更改当前进程的工作目录,也就是shell的工作目录,shell进程负责解释cd命令并调用chdir系统函数来更改路径。

crw-rw-rw-. 1 root root 1, 7 Jan 26 09:29 full /// 第一个字母c,代表character 设备 Documents/admin-guide/devices.txt
brw-rw----. 1 root disk 8, 0 Jan 26 09:29 sda ///第一个字母b,代表block设备
brw-rw----. 1 root disk 8, 1 Jan 26 09:29 sda1
brw-rw----. 1 root disk 8, 2 Jan 26 09:29 sda2

fdisk -l ,起始时读的文件/sys/dev/block/下面的文件来列出磁盘的情况

Linux 系统启动顺序:Power on,开机自检-> BIOS->如果选择磁盘启动,BIOS会到特定的磁盘位置找到Grub的启动点-> GRUB boot loader-> GRUB 根据配置找到linux kernel image,启动kernel-》然后再是kernel的启动顺序。->调用init 调用systemctl相关的服务进程

man -K grub

NAME
       grub-editenv — Manage the GRUB environment block.

SYNOPSIS
       grub-editenv [-v | --verbose] [FILE]
                     <create | list | set NAME=VALUE | unset NAME>

DESCRIPTION
       grub-editenv is a command line tool to manage GRUB's stored environment.

OPTIONS
       --verbose
              Print verbose messages.

       FILE
              File name to use for grub environment.  Default is /boot/grub/grubenv .

COMMANDS
       create
              Create a blank environment block file.

       list
              List the current variables.

       set [NAME=VALUE ...]
              Set variables.

       unset [NAME ...]
              Delete variables.

SEE ALSO
       info grub

cpio - copy files to and from archives

make help, 可以查看Makefile 提供的编译选项

读取文件

#!/bin/bash
file=/etc/resolv.conf
while IFS= read -r line; do 
	# echo line is stored in $line
	echo $line
done < "$file"

pid=$(< ${PIDFILE})

date +“%y%m%d”

to lower case

line1=echo ${line}|awk '{print tolower($0)}'

read action < /dev/tty

输入字符到action

case $Action in
                "e" | "E")
                    echo "You decided to exit."
                    exit 1
                    ;;
                "1")
                    echo "You selected 1"
                    break
                    ;;
                "2")
                    echo "You selected 1"
                    break
                    ;;
                *)
                ;;
esac   # 结束

判断是否为空, 前面加!,不为空

if [[ ! -z $temp ]] ; then

fi

判断文件是否存在

if [[ ! -f “${file}” ]]; then

执行命令后获取输出结果

archive_zip=$(eval ${cmd})
archive=·cmd·

unzip 到特定文件到特定目录

unzip -j file -d dir

分割字符取第二个

cut -d’:’ -f2

替换空格

/bin/sed ‘s/[[:space:]]//g’

文件中替换行

sed -i “/log_path/c $logpath” ansible.cfg
-i edit files in place (makes backup if SUFFIX supplied)
c
text Replace the selected lines with text, which has each embedded newline preceded by a backslash.

替换字符串

sed -e ‘s/1//’ -e 's/[ \t]. / / ′ 替换首尾空格 t a b 成空 ∣ s e d ′ s / [ : ] ∗ / ′ //' 替换首尾空格tab 成空 | sed 's/[^:]*/' //替换首尾空格tab成空seds/[:]/platform_type’/'2 |
sed ‘s/:{1}/& /g’` 替换一个冒号,成冒号加空格
s/regexp/replacement/
Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the special character & to refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.
sed s:${xmlpath}/::

所有参数

echo -e “ ( d a t e ) : " " (date): " " (date):""{@}” >> “${log_file}” // $@
$# 参数个数

echo 输出解释转义字符

-e enable interpretation of backslash escapes

时间

date +%T — 22:23:46

字符串组装

( p r i n t f m e d i a (printf media%02d " (printfmediaid")

数值计算

MAX_WAIT= ( ( 420 / 30 ) ) 啊 (( 420 / 30 )) 啊 ((420/30))(echo “2^8-1” |bc) 计算 2的8次方减1.
printf ‘%x\n’ $a // 转换16进制

数组操作

             pids=($(jobs -l % | grep -E -o '^(\[[0-9]+\]\+|    ) [ 0-9]{5} ' | sed -e 's/^[^ ]* \+//' -e 's! $!!'))
             PIDS[${NAME}]=${pids[0]}

while 循环

while [ 1 ]
do
done

for 循环

                 for (( i=0; i < MAX_WAIT; i++))
                 do
                     # Need to wait for
                     kill -0 "${pids[0]}" 2>/dev/null
                     ret=$?
                     if [[ "${ret}" != "0" ]]; then
                         break
                     fi
                     sleep 30
                 done

for MAP in /sys/firmware/memmap/* ; do echo “$(cat $MAP/start) - $(cat M A P / e n d ) ( MAP/end) ( MAP/end)((cat $MAP/type))” ; done
遍历文件;

比较 字符串

-z string
True if the length of string is zero.
string
-n string
True if the length of string is non-zero.

if [[ ${rpm_file} == debuginfo ]] 字符串比较

if [[ $# -le 2 ]]; then
if [[ $# -eq 0 ]]
if [[ -n $aa ]]; then

CONDITIONAL EXPRESSIONS
Conditional expressions are used by the [[ compound command and the test and [ builtin commands to test file attributes and perform string and arithmetic comparisons. Expressions are formed from the following unary or
binary primaries. If any file argument to one of the primaries is of the form /dev/fd/n, then file descriptor n is checked. If the file argument to one of the primaries is one of /dev/stdin, /dev/stdout, or /dev/stderr,
file descriptor 0, 1, or 2, respectively, is checked.

   Unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link, rather than the link itself. When used with [[, the < and > operators sort lexicographically using the current locale.  The test command sorts using ASCII ordering.

   -a file
          True if file exists.
   -b file
          True if file exists and is a block special file.

   -c file
          True if file exists and is a character special file.
   -d file
          True if file exists and is a directory.
   -e file
          True if file exists.
   -f file
          True if file exists and is a regular file.
   -g file
          True if file exists and is set-group-id.
   -h file
          True if file exists and is a symbolic link.
   -k file
          True if file exists and its ``sticky'' bit is set.
   -p file
          True if file exists and is a named pipe (FIFO).
   -r file
          True if file exists and is readable.
   -s file
          True if file exists and has a size greater than zero.
   -t fd  True if file descriptor fd is open and refers to a terminal.
   -u file
          True if file exists and its set-user-id bit is set.
   -w file
          True if file exists and is writable.
   -x file
          True if file exists and is executable.
   -G file
          True if file exists and is owned by the effective group id.
   -L file
          True if file exists and is a symbolic link.
   -N file
          True if file exists and has been modified since it was last read.
   -O file
          True if file exists and is owned by the effective user id.
   -S file
          True if file exists and is a socket.
   file1 -ef file2
          True if file1 and file2 refer to the same device and inode numbers.
   file1 -nt file2
          True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.
   file1 -ot file2
          True if file1 is older than file2, or if file2 exists and file1 does not.
   -o optname
          True if the shell option optname is enabled.  See the list of options under the description of the -o option to the set builtin below.
   -v varname
          True if the shell variable varname is set (has been assigned a value).
   -z string
          True if the length of string is zero.
   string
   -n string
          True if the length of string is non-zero.

   string1 == string2
   string1 = string2
          True if the strings are equal.  = should be used with the test command for POSIX conformance.

   string1 != string2
          True if the strings are not equal.

   string1 < string2
          True if string1 sorts before string2 lexicographically.

   string1 > string2
          True if string1 sorts after string2 lexicographically.

   arg1 OP arg2
          OP is one of -eq, -ne, -lt, -le, -gt, or -ge.  These arithmetic binary operators return true if arg1 is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to arg2, respec‐
          tively.  Arg1 and arg2 may be positive or negative integers.

case 或表达式

  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac

另一种if

if egrep -q “aa” <file_name> > /dev/null 2>&1
then
elif
fi

if && ||

[[ “ A C T I O N " = = " 11 " ∣ ∣ " {ACTION}" == "11" || " ACTION"=="11"∣∣"{ACTION}” == “22” ]]

读取参数

  parse_opts "$@"
  parse_opts function
     typeset opt_spec arg
           # Define the arguments
    opt_spec=":"
    opt_spec+="[-][a:-action]: "
    opt_spec+="[-][93:-nockpt] "
    opt_spec+="[-][94:-step]: "
    opt_spec+="[-][95:-toload]: "
    opt_spec+="[-][96:-tkey]: "    /// 前有-,或者没有,
    opt_spec+="[-][97:-fturl]: "

    opt_spec+="[-][98:-examples] "
    opt_spec+="[-][h:-help] "
    
    # parse command-line
    while getopts "${opt_spec}" arg ; do
            case "${arg}" in
            98)     # --examples
                    print "${GENERAL_USAGE}\n${EXAMPLES}"
                    scriptexit "${CURR_CMD}" 0
                    ;;
            97) # --fturl
                    fturl.found=1
                    fturl.value="${OPTARG}"
                    ;;

定义结构

action=( found=0; value=“” )
action.found=1
action.value=“${OPTARG}”

下载文件

curl -s -S -O url

移动参数

shift [n]
The positional parameters from n+1 … are renamed to $1 … Parameters represented by
the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or
equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to
be 1. If n is greater than $#, the positional parameters are not changed. The return
status is greater than zero if n is greater than $# or less than zero; otherwise 0.

参数个数

if (( ${#*} < 1 )); then

写log 到syslog

logger - a shell command interface to the syslog(3) system log module
logger -t ${tag} l o g o p t " {logopt} " logopt"{msg}"
logopt=“-s -p local3.error”
-t, --tag tag
Mark every line to be logged with the specified tag. The default tag is
the name of the user logged in on the terminal (or a user name based on
effective user ID).

循环字符串中的单词/数组

for word in ${line}

首先创建一个数组 array=(a b word) 和一句话的作用相同
for element in ${array[@]}
do
echo $element
done

算式

(( cnt++ ))

tr

tr - translate or delete characters
tr ‘\n’ ’ ’ //替换 换行到空格

xargs -n1

使用xargs 将字符串换行,按照空格隔开

获取 pid

pgrep -d " " name //用空格分开
ps -e -o pid,cmd

设置进程与cpu亲密度

taskset -p ${mask} ${vm_pid}
taskset is used to set or retrieve the CPU affinity of a running process given its pid, or to launch a new
command with a given CPU affinity. CPU affinity is a scheduler property that “bonds” a process to a given set
of CPUs on the system. The Linux scheduler will honor the given CPU affinity and the process will not run on
any other CPUs. Note that the Linux scheduler also supports natural CPU affinity: the scheduler attempts to
keep processes on the same CPU as long as practical for performance reasons. Therefore, forcing a specific
CPU affinity is useful only in certain applications.

获取主机名字

hostname

通过runcon运行命令

runcon -u system_u -r system_r

当前进程id

$$

环境变量

IFS

IFS The Internal Field Separator that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is ``‘’.
默认的内部分割符。

trap

根据手动的signal,信号,执行一些操作。
trap “rm -f ${LOCK_FILE};return 1” 1 2 15

错误

错误1 syntax error at line 67: `}’ unexpected

./add_subnet.sh: line 61: syntax error at line 67: `}’ unexpected
这里是说大括号,不太正常,
出现这个错误的一种情况:

echo "success add ${}"   # 忘记写参数名称。

错误2 ./add_subnet.sh: line 9: syntax error at line 32: `end of file’ unexpected

这个错误的意思是,语法错误,期望“end of file”标识。

出现的一种情况

commit_subnet()  ## 调用shell 函数时,使用了括号

错误3 subnetnum: not found [No such file or directory]

可能的原因是参数使用(展开)时,使用了小括号而不是大括号。
$(subnetnum)
${subnetnum}
这两个的区别,第一个是执行subnetnum命令;
第二个是参数subnetnum的展开。

实例

例一

#!/bin/ksh

total=2048
interval=500
(( remain = total % interval ))
(( loop = total / interval + 2 ))
for (( i=1; i < loop; i++))
do
	(( start = ( i - 1 ) * 500 + 1))
	if (( i == ( loop - 1 ) ))
	then
		(( interval = remain ))
	fi

	python a.py ${start} ${interval}
	if [[ $? != 0 ]]; then
		echo "generate file failure ${i}"
		exit 1
	fi
	/opt/bin/xml2cfg -h $(/opt/bin |awk '{print $1}') -p 9650 -i  publish_realm${start}.xml -o batch.out
	if [[ $? != 0 ]]; then
		echo "import configure failure ${i}"
		exit 2
	fi

	grep -q "Error" batch.out
	if [[ $? == 0 ]]; then
		echo "checkout result failure ${i}"
		echo "please check the batch.out file for detail error"
		exit 3
	fi

	echo "import success for${i}, at $(date)" 
	
done

实例二

# if the device exist, then execute following command to add vlan interface;
# and gateway ip
ip link show dd
if [[ $? == 0 ]]; then

	for (( i=1;i<2049;i++ ))
	do
		ip link add link dd name dd.${i} type vlan protocol 802.1Q id ${i}
		ip link set dev dd.${i} up
	done

	for (( i=1;i<2049;i++ ))
	do
		subnet=$(ip addr show dup1.$i | grep "10.87" | awk -F'.' '{print $3}')
		if [[ ! -z $subnet ]]; then
			ip addr add 10.87.${subnet}.254 dev dd.${i}
		fi
	done
	
else
	echo "there is no device for dd"
fi

bash vs ksh

对于bash 和 ksh,执行格式错误的可执行文件的错误提示不一样:
sh: /home/mzhan017/bin/tar: cannot execute binary file
ksh:/home/mzhan017/bin/tar.bak: /home/mzhan017/bin/tar.bak: cannot execute [Exec format error] 、、 这个提示的更明确一些。


  1. \t ↩︎

 类似资料: