Explicación detallada del script de Linux (shell)

descripción general

Script : es esencialmente un archivo que almacena instrucciones en un formato específico. El sistema puede usar el analizador de scripts para traducir o analizar las instrucciones y ejecutarlas (no es necesario compilarlo).

El shell es tanto un programa de aplicación escrito en C como un lenguaje de secuencias de comandos (Lenguaje de secuencias de comandos de análisis de aplicaciones)

Shell proporciona una interfaz a través de la cual los usuarios acceden a los servicios del kernel del sistema operativo.

El sh de Ken Thompson es el primer shell de Unix, y Windows Explorer es un típico shell de interfaz gráfica.


La programación Shell es lo mismo que la programación JavaScript y php, siempre que haya un editor de texto que pueda escribir código y un intérprete de script que pueda interpretar y ejecutar.

Hay muchos tipos de analizadores de comandos de shell para Linux, los más comunes son:

  • Bourne Shell (/usr/bin/sh o /bin/sh)
  • Bourne Again Shell (/bin/bash) (el shell predeterminado en la mayoría de los sistemas Linux)
  • Consola C (/usr/bin/csh)
  • Shell K(/usr/bin/ksh)
  • Shell para raíz (/ sbin / sh)

Este documento se enfoca en Bash , el Bourne Again Shell, que es ampliamente utilizado en el trabajo diario debido a su facilidad de uso y costo gratuito. Al mismo tiempo, Bash también es el shell predeterminado para la mayoría de los sistemas Linux. Ver el comando de analizador predeterminado de su sistema Linux: echo $SHELL

En general, las personas no distinguen entre Bourne Shell y Bourne Again Shell, por lo que, como #!/bin/sh , también se puede cambiar a #!/bin/bash .


Gramática detallada

Al escribir un archivo de script de shell, agregue una línea al principio: #!/bin/bash, porque no solo hay bash como analizador en Linux, sino también otros analizadores, y la sintaxis entre ellos será algo diferente, por lo que es mejor agregar esta oración para decirle al sistema que use este analizador.

#! es una marca de convención que le dice al sistema que el programa especificado por la ruta subsiguiente es el programa shell que interpreta este archivo de script.

Aviso:

  • Al envolver varios comandos en un script de shell, los comandos se ejecutan de arriba a abajo. Incluso si los comandos anteriores se ejecutan incorrectamente, los siguientes comandos se seguirán ejecutando.

  • Cuando escriba varios comandos en la misma línea en un script de shell, use un punto y coma (;) para separarlos. Incluso si el comando escrito en el frente no se ejecuta, el comando escrito en la parte posterior continuará ejecutándose.


expresión matemática

(( ))Es un comando de cálculo matemático de shell. A diferencia de C++, C#, Java y otros lenguajes de programación, no es tan conveniente realizar el cálculo de datos en el shell. Debe usar un comando de cálculo matemático especial, (( )) es uno de ellos.

+	 	# 加
-	 	# 减
*	 	# 乘
/	 	# 除
%	 	# 取余
**	 	# 幂

Variables de caparazón

clasificación de variables

Según la finalidad, se puede dividir en cuatro tipos de variables (la división de variables es diferente para cada libro):

  • Variables de entorno : un término colectivo para un grupo de variables establecidas para proporcionar el entorno operativo para el kernel del sistema, los comandos del sistema y las aplicaciones.

  • Variables internas : un término colectivo para un conjunto de variables establecidas específicamente para el shell

  • Variable de parámetro : los datos pasados ​​como parámetro. Los parámetros posicionales son datos que se pasan a funciones, bloques de instrucciones, etc., a los que se puede hacer referencia mediante $1 $2... $Ny con variables internas del shell (como, por ejemplo , etc.)$? $@

  • Variables definidas por el usuario : Variables establecidas por los propios usuarios. Se puede dividir en: variables locales y variables globales

    • Variables locales : variables que solo son válidas en bloques de código o funciones, y desaparecen cuando salen de bloques de código o funciones;

      Una variable local declarada en un bloque de código o función debe ser declarada por local, de lo contrario, también es visible para el proceso de shell actual.

    • Variable global : definida en el script, válida solo en el script de shell actual y no puede ser accedida por otros procesos de script de shell, y su alcance comienza desde la posición definida hasta el final del script o el lugar donde se muestra y elimina.

      Las variables globales se pueden actualizar a variables de entorno temporales ; declaradas a través de la exportación, de modo que los procesos secundarios del proceso actual también puedan usar esta variable.

      Las variables de entorno temporales solo son válidas para el entorno en ejecución. Si se ejecuta otro script de shell, esta variable de entorno temporal no tiene poder.


La diferencia y el uso de variables de entorno y variables internas (detalles: http://blog.sina.com.cn/s/blog_655047c00100hiao.html):

  • mismo:

    • Ambos se cargan tan pronto como se inicia el shell
    • Todos se combinan con referencias $, y todos existen en el script desde el principio, no es necesario que los usuarios vuelvan a configurar
  • diferente:

    • Las variables de entorno se pueden agregar, modificar y los usuarios pueden redefinir (detalles: https://blog.csdn.net/LLZK_/article/details/53813266)
    • Las variables internas de Shell son inmutables.

Variable ambiental

Una variable de entorno es un objeto con un nombre específico en el sistema operativo que contiene información que usarán una o más aplicaciones.

Linux es un sistema operativo multiusuario. Cada usuario tendrá un entorno operativo dedicado al iniciar sesión en el sistema. Por lo general, el entorno predeterminado para cada usuario es el mismo. Este entorno predeterminado es la definición de un conjunto de variables de entorno. Cada usuario puede configurar su propio entorno de ejecución modificando las variables de entorno.

Las variables de entorno están estrechamente relacionadas con el shell. Después de que el usuario inicia sesión en el sistema, se inicia un shell. Para Linux, generalmente es bash (Bourne Again shell, una extensión de Bourne shell (sh)), y también puede cambiar a otras versiones del shell.

bash tiene dos archivos de configuración básicos a nivel de sistema: /etc/bashrc y /etc/profile. Estos archivos de configuración contienen dos conjuntos diferentes de variables: variables de shell y variables de entorno. Las variables de shell son locales, mientras que las variables de entorno son globales. Las variables de entorno se establecen a través de comandos de shell. Las variables de entorno configuradas pueden ser utilizadas por todos los programas del usuario actual.


Clasificación de las variables de entorno

  • Según el ciclo de vida de las variables de entorno, se pueden dividir en variables de entorno permanentes y variables temporales
  • Según los diferentes niveles de usuario, se puede dividir en variables de nivel de sistema y variables de nivel de usuario

Variables permanentes (en todo el sistema) que se aplican a todos los usuarios:

Este tipo de variable tiene efecto para todos los usuarios del sistema y todos los usuarios pueden utilizar este tipo de variable. El ámbito de actuación es todo el sistema.

# 设置方式:
# 使用 vi 命令打开 /etc/profile 文件,用export指令添加环境变量
	
# 步骤示例:
# 1.打开配置文件,并按 i ,进入编辑模式
vi /etc/profile
# 2.在配置文件末尾添加环境变量
export 环境变量名(一般大写)="值"
# 3.使配置文件立即生效
source /etc/profile

# 注意:
	# 1. /etc/profile 只有root(超级用户)才能修改。可以在etc目录下使用 ls -l 查看这个文件的用户及权限
	# 2. 添加新的环境变量并退出配置文件后,需要执行命令 source /etc/profile 后才会立即生效。否则在下次重进此用户时才能生效

Variables persistentes que se aplican a un solo usuario (nivel de usuario)

Este tipo de variable de entorno surte efecto de forma permanente solo para el usuario actual. Es decir, si el usuario A establece una variable de entorno de este tipo, solo A puede usar esta variable de entorno. Y para otros usuarios B, C, D, E..., etc., esta variable no existe.

# 设置方法:在用户主目录”~”下的隐藏文件 “.bashrc”中添加自己想要的环境变量

# 步骤示例:
# 1.打开配置文件,并按 i ,进入编辑模式
vi ~/.bashrc
# 2.在配置文件末尾添加环境变量
export 环境变量名(一般大写)="值"
# 3.使配置文件立即生效
source ~/.bashrc

# 注意:
	# 系统中可能存在两个文件,.bashrc和.bash_profile(有些系统中只有其中一个)
	# 原则上来说设置此类环境变量时在这两个文件任意一个里面添加都是可以的。二者设置大致相同
      # ~/.bash_profile 是交互式login方式进入bash shell运行。即 .bash_profile 只会在用户登录的时候读取一次
      # ~/.bashrc 是交互式non-login方式进入bash shell运行。即 .bashrc 在每次打开终端进行一次新的会话时都会读取

# 查看隐藏文件(.XXX):
	# 方式1:命令 ls -al
	# 方式2:命令 echo .*

Variables de entorno temporalmente efectivas (solo válidas para el shell actual)

El alcance de la variable de entorno temporal es el script de shell actual y el shell de subproceso del proceso actual. Salga del script de shell actual y desaparezca

# 设置方法:直接使用export指令添加。 

Directivas comunes para variables de entorno

# 查看显示环境变量:echo,变量使用时要加上符号“$”
#例:
echo $PATH

# 设置新的临时环境变量 export
export 新临时环境变量名=内容 
# 例:
export MYNAME=”LLZZ”

# 修改环境变量没有指令,可以直接使用环境变量名进行修改。 
# 例:
MYNAME=”ZZLL”

# 查看所有环境变量
env

# 查看本地定义的所有shell变量
set
    
# 删除一个环境变量
unset 变量名
# 例:
unset MYNAME

Variables de entorno de uso común (todas en mayúsculas)

  • RUTA : vea la ruta de búsqueda de comandos. Al configurar la variable de entorno PATH, podemos ejecutar programas o comandos de manera más conveniente.
# 查看环境变量PATH
echo $PATH
# 说明:
	# 每一个冒号都是一个路径,这些搜索路径都是一些可以找到可执行程序的目录列表。
	# 当输入一个指令时,shell会先检查命令是否是内部命令,不是的话会再检查这个命令是否是一个应用程序。
	# 然后shell会试着从搜索路径,即PATH中寻找这些应用程序。
	# 如果shell在这些路径目录里没有找到可执行文件。则会报错。
	# 若找到,shell内部命令或应用程序将被分解为系统调用并传给Linux内核。

# 示例: 
# 现在有一个c程序test.c通过gcc编译生成的可执行文件a.out(功能:输出helloworld)。平常执行这个a.out的时候是使用 
  # 方式1:相对路径调用:./a.out  (”.”代表当前目录,”/”分隔符)
  # 方式2:绝对路径调用:/home/lzk/test/a.out 
  # 方式3:通过设置PATH环境变量,直接用文件名调用: a.out (只要可以通过PATH中路径找得到这个可执行文件)
  
# 使用export指令添加PATH中的路径
# 示例:将a.out的路径添加到搜索路径当中
export PATH=$PATH:路径   		# PATH中路径是通过冒号“:”进行分隔的,把新的路径加在最后就OK
  • INICIO : especifique el directorio de trabajo principal del usuario, que es el directorio predeterminado cuando el usuario inicia sesión en el sistema Linux, a saber, "~"

  • HISTSIZE : guarda el número de registros de comandos históricos.

    Los comandos ingresados ​​por el usuario serán guardados por el sistema, y ​​esta variable de entorno registra el número de comandos guardados. Generalmente 1000

    Estos comandos históricos se guardan en el archivo oculto .bash_profile en el directorio de inicio de trabajo del usuario "~"

    Puedes verlo por historial de comandos

  • LOGNAME : se refiere al nombre de inicio de sesión del usuario actual

  • HOSTNAME : Se refiere al nombre del host

  • SHELL : se refiere a qué shell está usando el usuario actual

  • LANG/LANGUGE : variables de entorno relacionadas con el idioma, los usuarios que usan varios idiomas pueden modificar esta variable de entorno

  • CORREO : Se refiere al directorio de almacenamiento de correo del usuario actual

  • PS1 : el símbolo del sistema de Shell de primer nivel, el usuario raíz es # y el usuario normal es $

  • PS2 : el símbolo del sistema de Shell de segundo nivel, el valor predeterminado es ">"

  • PS3 : El símbolo del sistema de shell de tercer nivel. Se utiliza principalmente para indicaciones de selección de menú para seleccionar estructuras de control de bucle

  • TMOUT : valor de tiempo de espera para la interacción del usuario y el sistema

    Cuando el sistema interactúa con el usuario, el sistema solicita al usuario que ingrese, pero el usuario no ingresa durante mucho tiempo. Después de que el tiempo exceda el valor establecido por TMOUT, el shell finalizará la ejecución debido al tiempo de espera.


Variables internas de shell

variable de posición (variable de parámetro)

Al ejecutar un script de shell, si desea obtener la información del parámetro pasado desde la línea de comando, debe usar variables de posición, como: ./myshell.sh 100 200 puede entenderse como el método de paso de parámetros del script de shell

# 预定义变量		# 功能描述
$n			# n为数字
			  # $0表示命令本身(执行脚本的命令)
			  # $1-9代表第一个参数到第九个参数
			  # 10以上的参数需要使用大括号进行包裹如:${10}
$*			# 传递给函数或脚本的所有参数
$@			# 传递给函数或脚本的所有参数
$#			# 代表参数的个数

# 注:
	# $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
	# 但是当它们被双引号(" ")包含时,
		# "$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;
		# "$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数

variable predefinida

Variables predefinidas: variables que han sido definidas por el diseñador de shell de antemano y se pueden usar directamente en scripts de shell

# 预定义变量		# 功能描述
$?			# 命令执行后返回的状态
$$			# 当前进程的进程号(PID)
$! 			# 最近运行的一个后台进程的进程号(PID)
$?			# 最后一次执行的命令的返回状态
			  # 若返回 0 :则上一个命令正确执行;若返回 非0(具体数值由命令自己决定),则上一个命令未正常执行

$LINENO		# 调测用。用于显示脚本中当前执行的命令的行号
$OLDPWD		# 配合cd命令改换到新目录之前所在的工作目录
			  # 用法:cd $OLDPWD  (切换到之前的工作目录,和cd - 功能一样)
$PPID		# 当前进程的父进程的PID
$PWD		# 当前工作目录。等同于命令pwd的输出
$RANDOM		# 随机数变量。每次引用这个变量会得到一个0~32767的随机数
$REPLY		# 通过read命令读入的数据,如果没有被赋值指定变量,则默认赋值到 REPLY 变量中
$SECONDS	# 脚本已经运行的时间(以秒为单位)

Variables personalizadas: definición, asignación

Las variables son una parte esencial de cualquier lenguaje de programación, y las variables se utilizan para almacenar diversos datos. Los lenguajes de secuencias de comandos generalmente no necesitan especificar el tipo al definir variables, solo asignan valores directamente, y las variables de Shell también siguen esta regla.

En el shell Bash, el valor de cada variable es una cadena, independientemente de si la variable se asigna con comillas o no, el valor se almacenará en forma de cadena.

Las variables de shell son diferentes de algunos lenguajes de programación. Generalmente, las variables de shell no necesitan incluirse al asignar valores “$”, pero deben incluirse al usar o generar “$”. Al sumar, restar, multiplicar y dividir, use doble paréntesis. Debe haber uno fuera de los corchetes “$”, y las variables dentro de los corchetes se pueden omitir “$”.


definir variables

Shell admite las siguientes tres formas de definir variables:

variable=value
variable='value'
variable="value"

ilustrar:

  • variable es el nombre de la variable, valor es el valor asignado a la variable

  • Si el valor no contiene ningún espacio en blanco (como espacios, sangría de tabulación, etc.), entonces no puede usar comillas

  • Si el valor contiene caracteres en blanco, debe estar entre comillas simples y dobles

    Análisis: después de leer el comando, la cadena o palabra clave se cortará de acuerdo con el espacio. Después del corte, se dividirá en dos partes: y, que se c=heentiende llocomo c=heuna asignación variable, pero llono se puede encontrar ningún elemento coincidente y el comando relevante no se puede recuperar, por lo que llose mostrará este error.

  • Los únicos tipos de variables en los scripts de shell son enteros y cadenas.

Aviso:

  • No puede haber espacios alrededor del número de asignación =, de lo contrario, se analizará en un comando, y dicho comando no se informará como un error. Este probablemente no sea el caso con los lenguajes de programación más comunes.

Convenciones de nomenclatura para variables de shell:

  • Los nombres de las variables se componen de números, letras y guiones bajos;
  • Debe comenzar con una letra o guión bajo;
  • Las palabras clave en el shell no se pueden usar (las palabras clave reservadas se pueden ver a través del comando de ayuda).

La diferencia entre comillas simples y comillas dobles:

Al definir una variable, el valor de la variable está entre comillas simples ' 'y comillas dobles " ":

  • Al encerrar el valor de una variable con comillas simples ' ', se mostrará lo que esté dentro de las comillas simples, incluso si hay variables y comandos en el contenido (los comandos deben invertirse), se mostrarán como están. Este método es más adecuado para definir y mostrar cadenas puras, es decir, escenarios en los que no desea analizar variables, comandos, etc.

  • Cuando el valor de la variable está entre comillas dobles " ", las variables y los comandos internos se analizarán primero al generar, en lugar de generar los nombres de las variables y los comandos entre comillas dobles como están. Este método es más adecuado para definiciones de variables que tienen variables y comandos adjuntos a la cadena y desean analizarlos antes de enviarlos.

sugerencia:

  • Si el contenido de la variable es un número, puede estar sin comillas
  • Si necesita mostrarlo tal como está, agregue comillas simples
  • Es mejor agregar comillas dobles para otras cadenas que no tengan requisitos especiales. Agregar comillas dobles al definir variables es el escenario de uso más común

Ejemplo:

#!/bin/bash

a=10
b=20
c="this is a test"
d=$((a+b))
f=test					# 变量赋值的时候如果只有一个单词可以不用加引号
time=`date`				# date 命令用来获得当前的系统时间
date=`date +%s`    		# data 命令的 %s 格式控制符可以得到当前的 UNIX 时间戳,可以用于计算脚本的运行时间
							# UNIX 时间戳是指从 1970 年 1 月 1 日 00:00:00 到目前为止的秒数

echo $c					
echo "a = "$a          # 输出a的
echo "a+b = "$((a+b))  # 输出a+b的值
echo $((a+b*a-b/a+a%b+a**2)) #表达式可以很长

asignación de variables

# 方式1:“=”并初始化
var=value  		# 注意:如果value是带有空格的字符串,需要加单或双引号

# 方式2:“=”不初始化
var=			# 未赋值变量,值为null

# 方式3:read命令
# read命令是读取标准输入的数据,然后存储到指定的变量中。注意:read接收的是标准输入而不是参数,read命令是不接收参数的。

Variables personalizadas: referenciar, modificar, eliminar

referencia variable

# 方式1
$variable

# 方式2(变量名外面的花括号 { }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界)。推荐
${variable}

# 方式3$variable”或“${variable}# 注:引用变量后,双引号会对于引用结果中空格和一些特殊符号进行的解析或者不解析。而引用结果用的空格在命令中的分隔作用会完全改变一个命令的输出,而特殊符号的是否解析也会影响最终的输出结果。
skill="Java"
echo "I am good at ${skill}Script"
# 如果不给 skill 变量加花括号,写成`echo "I am good at $skillScript"`,解释器就会把 $skillScript 当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。

Modificar el valor de una variable

Las variables definidas se pueden reasignar, como:

url="http://c.biancheng.net"
echo ${url}
# 第二次对变量赋值时不能在变量名前加 $,只有在使用变量时才能加 $
url="http://c.biancheng.net/shell/"
echo ${url}

borrar variable

Las variables se pueden eliminar con el comando unset .

gramática:

unset variable_name

Aviso:

  • Después de eliminar una variable, no se puede volver a utilizar
  • El comando unset no puede eliminar variables de solo lectura

Ejemplo:

#!/bin/sh
myUrl="http://c.biancheng.net/shell/"
unset myUrl
echo $myUrl				# 会没有任何输出

Variables personalizadas: establecer solo lectura

Utilice el comando de solo lectura para definir una variable como una variable de solo lectura, y el valor de la variable de solo lectura no se puede cambiar.

El siguiente ejemplo intenta cambiar una variable de solo lectura y da como resultado un error:

#!/bin/bash

myUrl="http://c.biancheng.net/shell/"
readonly myUrl
myUrl="http://c.biancheng.net/"				# 会报错

Sustitución de comandos de Shell: asignar el resultado del comando a una variable

Shell también admite asignar el resultado de ejecución de un comando a una variable. Hay dos formas comunes:

# 两种方式可以完成命令替换,一种是$(),一种是反引号` `
variable=$(commands)
variable=`commands`
# 说明:
	# 1.variable 是变量名,commands 是要执行的命令
	# 2.commands 可以只有一个命令,也可以有多个命令,多个命令之间以分号;分隔

Aviso:

  • Si la salida del comando reemplazado incluye varias líneas (es decir, hay caracteres de nueva línea) o contiene varios caracteres en blanco consecutivos, entonces la variable debe estar entre comillas dobles al generar la variable; de ​​lo contrario, el sistema usará el carácter en blanco predeterminado para completar, lo que hará que la nueva línea no sea válida, y los caracteres en blanco consecutivos se comprimirán en uno solo, lo que generará confusión en el formato.

  • Las dos formas de sustitución de variables son equivalentes y se pueden utilizar a voluntad.

  • Los acentos graves y las comillas simples son muy similares, lo cual es fácil de causar confusión, por lo que no se recomienda este método;

    El uso $() es relativamente claro y debe usarse en algunos casos $(), como $() el anidamiento de apoyo, y no se permiten las comillas invertidas.

  • $()Válido solo en el shell Bash, mientras que los acentos graves funcionan en muchos shells.


Expresiones de variables de shell

# 	表达式				  # 	说明
${
    
    #string}				# 计算$string的长度
${string:position}		# 从pos位置开始提取字符串
${string:position:len}	# 从pos位置开始提取长度为len的字符串
${string#substr}		# 从开头删除最短匹配子串
${string##substr}		# 从开头删除最长匹配子串
${string%substr}		# 从结尾删除最短匹配子串
${string%%substr}		# 从结尾删除最长匹配子串

 # 注意:字符串的长度包括空格,但是没有像C语言中那种'\0'字符

ejemplo

#!/bin/bash

str="a b c d e f g h i j"

echo "the source string is "${str}                         #源字符串
echo "the string length is "${
    
    #str}                        #字符串长度
echo "the 6th to last string is "${str:5}                  #截取从第五个后面开始到最后的字符
echo "the 6th to 8th string is "${str:5:2}                 #截取从第五个后面开始的2个字符
echo "after delete shortest string of start is "${str#a*f} #从开头删除a到f的字符
echo "after delete widest string of start is "${str##a*}   #从开头删除a以后的字符
echo "after delete shortest string of end is "${str%f*j}   #从结尾删除f到j的字符
echo "after delete widest string of end is "${str%%*j}     #从结尾删除j前面的所有字符包括j

Juicio de prueba de Shell: prueba, [ ], [[ ]]

El comando de prueba y [ ] en el Shell se utilizan para verificar si una determinada condición es verdadera y puede realizar pruebas en tres aspectos: valor numérico, carácter y archivo.

[[ ]] es una palabra clave del lenguaje de programación bash. No es un comando, la estructura [[ ]] es más general que la estructura [ ]. Todos los caracteres entre [[ y ]] no sufrirán expansión de nombre de archivo ni división de palabras, pero sí expansión de parámetros y sustitución de comandos. Admite la coincidencia de patrones de cadenas e incluso expresiones regulares de shell cuando se usa el operador =~. Al comparar cadenas, el lado derecho se puede usar como un patrón, no solo como una cadena, como [[ hola == diablos? ]], el resultado es verdadero. [[ ]] coincide con cadenas o comodines sin comillas.

El uso de la construcción condicional [[ ]] en lugar de [ ] evita muchos errores lógicos en los scripts. Por ejemplo: los operadores &&, ||, <, > normalmente pueden existir en la estructura de juicio de condición [[ ]], pero si aparecen en la estructura [ ], se informará un error. Por ejemplo, se puede usar directamente if [[ $a !=1 && $a != 2 ]], o si no se if [ $a -ne 1] && [ $a != 2 ]usan corchetes dobles if [ $a -ne 1 -a $a != 2 ].

bash trata la expresión encerrada entre corchetes dobles como un solo elemento y devuelve un código de estado de salida.

Nota: Al usar [ ], debe haber espacios entre cada variable, y debe haber espacios entre los corchetes izquierdo y derecho, de lo contrario se informará un error.

prueba numérica

parámetro ilustrar
-eq cierto si es igual a
- es cierto si no es igual
-gt cierto si es mayor que
-ge Verdadero si es mayor o igual que
-lt cierto si es menor que
- el verdadero si es menor o igual que

prueba de cuerda

parámetro ilustrar
= cierto si es igual a
!= cierto si no es igual
cadena -z Verdadero si la longitud de la cadena es cero
-n cadena Verdadero si la longitud de la cadena no es cero

prueba de archivo

parámetro ilustrar
-e nombre de archivo Verdadero si el archivo existe
-f nombre de archivo Verdadero si el archivo existe y es un archivo normal
-d nombre de archivo Verdadero si el archivo existe y es un directorio
-r nombre de archivo Verdadero si el archivo existe y es legible
-w nombre de archivo True si el archivo existe y se puede escribir
-x nombre de archivo Verdadero si el archivo existe y es ejecutable
-s nombre de archivo Verdadero si el archivo existe y tiene al menos un carácter
-c nombre de archivo Verdadero si el archivo existe y es un archivo especial de caracteres
-b nombre de archivo Verdadero si el archivo existe y es un archivo especial de bloque

ejemplo

#!/bin/bash

# 文件测试
echo "Please input two numbers:"
read num1
read num2

echo "num1 = "${num1}
echo "num2 = "${num2}
echo -e "by test\n"
test $num1 -eq $num2 && echo "num1 == num2" || echo "num1 != num2"
echo -e "by []\n"
[ $num1 -eq $num2 ] && echo "num1 == num2" || echo "num1 != num2"


# 数值测试
echo "Please input a filename: "
# 从标准输入获取一个文件名,并存入filename变量中
read filename
echo -e "by test\n"
test -f $filename && echo "这是一个普通文件" || echo "这不是一个普通文件"
echo -e "by []\n"
[ -f $filename ] && echo "这是一个普通文件" || echo "这不是一个普通文件"

Operadores lógicos: Y, O, NO

Shell también proporciona y (-a) , o (-o) , no (!) Tres operadores lógicos para conectar las condiciones de prueba, y su prioridad es: ! es el más alto, -a es el segundo y -o es el más bajo.

Ejemplo:

#!/bin/bash

# 逻辑操作符和字符串测试
echo "Please input a city name: "
# 从标准输入获取一个值,并存入city变量中
read city
if "成都" = $city -o "南京" = $city
then
    echo '城市是成都或南京'
else
    echo '城市既不是成都也不是南京'
fi

Declaración de estructura de rama condicional de Shell

declaración de una sola rama

Formato:

if 条件 ; then 结果; fi

# 最后面一定要有fi,在shell脚本里面,控制分支结构结束都要和开头的单词相反,例如,if <–> fi,case <–> esac

ejemplo

#!/bin/bash

echo "Please input a filename"
# read filename:表示从标准输入获取一个文件名,并存入felename变量中
read filename
if [ -f $filename ]
then
	echo "this file is a ordinary file."
fi

declaración de doble rama

Formato:

if 条件 ; then 结果; else 结果; fi

ejemplo

#!/bin/bash

echo "Please input a filename"
read filename
if [ -f $filename ]
then
	echo "this file is a ordinary file."
else
	echo "this file is not a ordinary file."
fi

Declaración de juicio de múltiples ramas

Hay dos tipos de juicios de múltiples ramas (igual que el lenguaje C): if-else if y case

gramática:

if 条件 ; then 结果; elif 条件; then 结果; else 结果; fi

si-si no si ejemplo

#!/bin/bash

echo "Please input your math grades"
read grades

if [ $grades -gt 100 ] || [ $grades -lt 0 ];then
echo "Please input the number range in 0 - 100"
fi

if [ $grades -ge 90 ] && [ $grades -le 100 ]
then
	echo "Your grade is excellent."
elif [ $grades -ge 80 ] && [ $grades -le 89 ];then
	echo "Your grade is good."
elif [ $grades -ge 70 ] && [ $grades -le 79 ];then
	echo "Your grade is middle."
elif [ $grades -ge 60 ] && [ $grades -le 69 ];then
	echo "Your grade is passing."
else
	echo "Your grade is badly."
fi

ejemplo de caso

#!/bin/bash

echo "Please input a command"
read cmd
case $cmd in
cpu)    echo "The cpu information is"
        cat  /proc/cpuinfo;;
mem)    echo "The mem information is"
        cat /proc/meminfo;;
device) echo "The device information is"
        cat /proc/scsi/device_info;;
CD-ROM) echo "The CD-ROM information is"
        cat /proc/sys/dev/cdrom/info;;
*)      echo "Your input command is invalid"
esac

instrucción de bucle de shell

para declaración

Formato:

for 变量 in 列表
do
语句
done

ejemplo

#!/bin/bash

arr=("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c" "e" "e" "f")

# 遍历(不带数组下标。* 和 @ 均可)
for value in ${arr[*]}
do
echo $value
done

# 遍历(带数组下标)
for (( i = 0 ; i < ${#arr[@]} ; i++ ))
do
echo ${arr[$i]}
done

mientras declaración

La instrucción while ejecuta la siguiente instrucción siempre que la condición sea verdadera.

Formato:

while 条件
do
语句
done

Cabe señalar que las condiciones aquí pueden escribirse de esta manera, excepto si son verdaderas, y otras condiciones deben juzgarse mediante pruebas o []

ejemplo

# -----------文件名为test.sh-----------
#!/bin/bash

# $1 为调用脚本时的第1个传参
i=$1
while [ $i -gt 0 ]
do
echo $i
((i--))
done

# -----------调用-----------
sh test.sh 10		# 文件名test.sh 后面跟的是参数,$0代表文件名,$1代表第一个参数...

hasta declaración

La declaración hasta es ejecutar la siguiente declaración siempre que la condición sea falsa

Formato:

until 条件
do
语句
done

ejemplo

#!/bin/bash

i=$1
until [ $i -le 0 ]
do
echo $i
((i--))
done

Función de caparazón

Formato:

[function] funcName()
{
    
    undefined
语句
[return 返回值]
}

ilustrar:

  • El valor de retorno de la función de shell return solo puede ser un número entero, que generalmente se usa para indicar si la función se ejecuta con éxito o no, 0 indica éxito y otros valores indican falla. Si se devuelven otros datos, como una cadena, se informará un mensaje de error: "argumento numérico requerido".

  • return 返回值es opcional; si no hay devolución, se devolverá por defecto el valor de estado del éxito o fracaso de la última declaración

  • El parámetro posicional se usa para pasar parámetros a la función; el uso del parámetro posicional en la función: from $1to $n, $0es el nombre del archivo

Método de llamada de función:

# 方式1:调用函数,然后再使用预定义变量 $? 获取函数返回值
function_name [arg1 arg2 ......]
$?

# 方式2:调用函数并将函数的标准输出赋值到一个变量中。注意:不是返回值
value=`function_name [arg1 arg2 ......]`
value=$(function_name [arg1 arg2 ......])

Ejemplo:

#!/bin/bash

#打印数字
printNum()
{
    
    
   echo $1				# 位置参数的使用
}

for i in `seq 2 8` 		# seq是一个命令,顺序生成一串数字或者字符
do
printNum $i				# 位置参数的传参
done

Cómo la función genera una cadena:

Use acentos graves ``para asignar la salida estándar de la función a una variable, y el script accede a esta variable para obtener el valor de salida de la función cuando sea necesario.

Nota: si la salida estándar se realiza varias veces en la función, todos los valores de salida se asignarán a la variable juntos. Se recomienda que la salida estándar se realice solo una vez dentro de una función.

#!/bin/bash

# 函数输出字符串
getString()
{
    
    
   echo "abc"
   return 0
}
# 函数输出赋值
value=`getString`
# 使用
echo ${value}-xxxx

Cómo se ejecutan los scripts de shell

(El siguiente método especifica que el script puede usar una ruta absoluta o una ruta relativa)

  • Path/xxx.sh : primero analice de acuerdo con el analizador especificado por #! en el archivo . Si el analizador especificado por #! no existe, se utilizará el analizador predeterminado del sistema.

    Aviso:

    • Este método requiere que el archivo ejecutable tenga permiso de ejecución (x) ( chmod +x 文件名: agregar permiso de ejecución a todas las identidades del archivo); de lo contrario, se informará un error
    • De esta forma, aunque el script esté en la ruta actual, debe especificarse: ./xxx.sh
  • bash xxx.sh : indica que el analizador bash se usa para analizar primero, y el analizador predeterminado se usará si bash no existe

  • sh xxx.sh : utiliza directamente el analizador predeterminado para analizar. Puede usar rutas relativas o rutas absolutas

  • .xxx.sh : use directamente el analizador predeterminado para analizar Nota: hay un espacio directamente entre el .(punto) y el nombre del archivo


expandir

Obtener el comando de secuencia de comandos de dirección IP local

Método 1: dirección IP

En el caso de múltiples tarjetas de red, también se devuelve la primera IP

ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}' | sed -n '1p'

Shell método dos:ifconfig -a

ifconfig -a | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' | tr -d "addr:"

# 命令解析
-  ifconfig -a       和window下执行此命令一样道理,返回本机所有ip信息
-  grep inet           截取包含ip的行
-  grep -v 127.0.0.1    去掉本地指向的那行
-  grep -v inet6        去掉包含inet6的行
-  awk {
    
     print $2}      $2 表示默认以空格分割的第二组 同理 $1表示第一组
-  tr -d "addr:         删除"addr:"这个字符串

Múltiples NIC

Si hay varias tarjetas de red, puede haber varias direcciones IP de diferentes segmentos de red. En este momento, si aún se ejecuta el comando anterior, se devolverán varias direcciones IP, de la siguiente manera:

Supongamos que cierta máquina tiene IPs de 192. . .8 y 10. . .* segmentos de red, y ahora es necesario imprimir diferentes salidas para direcciones IP de diferentes segmentos de red, el script de shell es el siguiente

#!/bin/sh
ip=`ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"`
echo $ip
if[[ $ip =="10."*]]
then
echo "该网段是10.*.*.*网段"
else
echo "该网段是192.*.*.*网段"
fi

Comando jq: manipular JSON

Referencia: https://www.cnblogs.com/kumufengchun/p/10799888.html

El comando jq permite realizar operaciones en JSON directamente desde la línea de comando, incluidas la fragmentación, el filtrado, la conversión, etc.

jq está escrito en C.

Los archivos binarios precompilados de jq pueden ejecutarse directamente en sistemas Linux, OS X y Windows, y pueden instalarse directamente con yum en sistemas Linux.

Prepare la cadena json: kumufengchun.json

{
    
    
    "name":"kumufengchun",
    "age":"18",
    "city":"beijing",
    "email":"[email protected]",
    "date":"Thursday",
    "country":"China",
    "company":["baidu","google","alibaba"]
}

Prepare la cadena json:

[
    {
    
    
        "name":"JSON", 
        "good":true
    }, 
    {
    
    
        "name":"XML", 
        "good":false
    }
]

Uso básico de jq

# 用jq .直接查看json文件内容
# 方式1
jq . kumufengchun.json 
# 方式2
cat kumufengchun.json | jq .


# 输出某个字段或者某个索引的值
# 语法:
jq  '.<key>'  			# 这里key是字段名称
# 实例
jq .name kumufengchun.json
# 输出:"kumufengchun"
# 使用 -r 参数,不含双引号输出结果
jq -r .name kumufengchun.json
# 输出: kumufengchun


# 输出数组的值
# 语法:
jq '.<key>[<value>]' 		# 这里value是数组的索引整数值
# 实例
jq '.company[0]' kumufengchun.json

# 输出列表、数组的一部分,对其进行切片
# 语法:
jq '.<list-key>[s:e]'		# 返回的是数组或者列表的index从s开始(包括s)到e结束(不包括e)
# 实例
jq '.company[0:2]' kumufengchun.json
# 也可以省略开始的index,只有结束的index,如下,仍然是不包括结束index的值
jq '.company[:3]' kumufengchun.json
# 也可以省略结束的index,只有开始的index,如下,输出到最后
jq '.company[1:]' kumufengchun.json
# 开始的索引也可以是负数,表示从后边倒着数,从-1开始数
jq '.company[-2:]' kumufengchun.json


# 循环输出所有的值,如数组嵌套
# 语法:
jq '.[]'
# 实例
jq '.[]' test.json 


# 输出多个索引的值,可以用逗号分割
# 语法:
jq '.key1,.key2'
# 实例
jq '.name,.age' kumufengchun.json
# 如果是数组,用中括号括起来要输出的键值,键值先写谁,先输出谁
jq '.company[2,0]' kumufengchun.json


# 用管道符号|可以对其进行再次处理
# 语法:
jq .[] | .<key1>
# 实例
jq '.[]|.name' test.json


# 括号的作用
echo 1 | jq '(.+2)*5'
# 输出:
15
echo {
    
    1,2,3} | jq '(.+2)*5'
# 输出:
15
20
25

# length求长度,如果是字符串是求的字符串的长度,如果是数组则求得是数组的长度
cat kumufengchun.json | jq '.[] | length'


# 输出所有的keys
# 语法: 
jq keys
# 实例
cat kumufengchun.json | jq 'keys'
# 输出数组的keys(索引)
cat kumufengchun.json | jq '.company | keys'


# 判断存不存在某个键
cat kumufengchun.json | jq 'has("email")'
# 输出:
true

Obtenga el valor de retorno del comando anterior de tee

Para los comandos en la tubería, el uso $?solo puede obtener el valor de retorno del último comando en la tubería

PIPESTATUS[n], obtenga el valor de retorno del comando n en la canalización

Ejemplo:

cp abc def 2>&1 | tee a.log
# ${PIPESTATUS[0]} 获取的是 cp 命令的返回值
test ${
    
    PIPESTATUS[0]} -ne 0 && exit

eval: ejecuta el comando de cadena

#!/bin/bash
cmd="mkidr aaa"
eval $cmd

interceptación de cadenas

var=http://www.aaa.com/123.htm

# 1. # 号截取,删除左边字符,保留右边字符
echo ${var#*//}
  # 其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符
  # 即删除 http://
  # 结果是 :www.aaa.com/123.htm

# 2. ## 号截取,删除左边字符,保留右边字符。
echo ${var##*/}
  # ##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符
  # 即删除 http://www.aaa.com/
  # 结果是 123.htm

# 3. %号截取,删除右边字符,保留左边字符
echo ${var%/*}
  # %/* 表示从右边开始,删除第一个 / 号及右边的字符
  # 结果是:http://www.aaa.com
 
# 4. %% 号截取,删除右边字符,保留左边字符
echo ${var%%/*}
  # %%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
  # 结果是:http:

# 5. 从左边第几个字符开始,及字符的个数
echo ${var:0:5}
  # 其中的 0 表示左边第一个字符开始,5 表示字符的总个数。
  # 结果是:http:

# 6. 从左边第几个字符开始,一直到结束。
echo ${var:7}
  # 其中的 7 表示左边第8个字符开始,一直到结束。
  # 结果是 :www.aaa.com/123.htm
  
# 7. 从右边第几个字符开始,及字符的个数
echo ${var:0-7:3}
  # 其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
  # 结果是:123

# 8. 从右边第几个字符开始,一直到结束
echo ${var:0-7}
  # 表示从右边第七个字符开始,一直到结束。
  # 结果是:123.htm
  
# 注:(左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示)

La secuencia de comandos principal detecta el aborto de la secuencia de comandos secundaria (proceso secundario)

  • exit 0: ejecuta el programa normalmente y sale del programa;

  • exit 1: Salir del programa debido a una operación anormal; el valor después de la salida es mayor que 0, todos salen anormalmente

  1. Un subíndice aborta manualmente

    #!/bin/bash
    # 子脚本
    echo aaa && exit 1
    
  2. $?El script principal obtiene el valor de retorno del script secundario a través del comando (cuando hay un comando tee, use el comando ${PIPESTATUS[0]}`)


Shell script carga otro script

#!/bin/bash

# 方式1:source		# 注意:被加载的脚本,不能缺省路径
source ./first.sh

# 方式2:点号(.)		   # 注意:1.被加载的脚本,不能缺省路径。2.点号与脚本文件之间记得要有空格
. ./first.sh
  • Usar el comando fuente es equivalente al punto (.), similar a la directiva de preprocesamiento #include en C/C++, que carga el contenido del script especificado en el script actual y lo ejecuta mediante un proceso de Shell.
  • El uso del comando sh para llamar a otro script abrirá un nuevo proceso de Shell para ejecutar el script especificado y no se podrá acceder a las variables del proceso principal en el proceso secundario.

Habilitar subprocesos

El subshell se implementa usando () en el script de Linux, es decir, el código en () se ejecutará en el subshell

おすすめ

転載: blog.csdn.net/footless_bird/article/details/123698139