Programación de shell. Lenguaje de comandos de shell. quien lo necesita

  • Tutorial

¿Por qué y para quién es el artículo?

Inicialmente, esto fue un recordatorio para los estudiantes que comienzan a trabajar con sistemas tipo Unix. En otras palabras, el artículo está dirigido a quienes no tienen experiencia previa trabajando en un sistema Unix. línea de comando, pero por una razón u otra quiere o necesita aprender a interactuar eficazmente con él.

No se volverá a contar mana (documentación) y el artículo no cancela ni reemplaza de ninguna manera su lectura. En su lugar, hablaré sobre los aspectos principales (comandos, técnicas y principios) que es necesario comprender desde el principio cuando se trabaja en el shell Unix para que el trabajo sea eficaz y agradable.

El artículo trata sobre entornos completos tipo Unix, con un shell completamente funcional (preferiblemente zsh o bash) y una gama bastante amplia de programas estándar.

que es la concha

Shell (shell, también conocido como “línea de comando”, también conocido como CLI, también conocido como “consola”, también conocido como “terminal”, también conocido como “ventana negra con letras blancas”) es interfaz de texto comunicación con Sistema operativo(bueno, estrictamente hablando, esto es programa, que proporciona dicha interfaz, pero ahora esta diferencia es insignificante).

En general, trabajar a través de un shell se ve así: el usuario (es decir, usted) ingresa un comando desde el teclado, presiona Enter, el sistema ejecuta el comando, escribe el resultado de la ejecución en la pantalla y nuevamente espera la entrada. siguiente comando.

Vista típica shella:

El shell es la forma principal de interactuar con todos los sistemas de servidor tipo Unix.

¿Dónde se encuentran los sistemas de línea de comando?

Donde un shell Unix podría estar esperándote, opciones populares:
  • MacOS (golpe);
  • acceso remoto al servidor para trabajar o para un proyecto web personal;
  • servidor de archivos doméstico con acceso remoto;
  • Ubuntu, PC-BSD en computadora portátil/escritorio - sistemas tipo unix hoy en día son fáciles de instalar y utilizar.

¿Qué problemas es razonable resolver con un caparazón?

Tareas naturales para las que la concha es apta, útil e indispensable:
  • trabajo interactivo en la terminal:
    • compilar, ejecutar trabajos mediante make;
    • comparación de archivos de texto;
    • análisis rápido de datos ad-hoc (número de IP únicas en el registro, distribución de registros por horas/minutos, etc.);
    • acciones masivas únicas (eliminar muchos procesos; si trabaja con un sistema de control de versiones, revertir o resolver un montón de archivos);
    • diagnóstico de lo que está sucediendo en el sistema (semáforos, bloqueos, procesos, descriptores, espacio en disco, etc.);
  • secuencias de comandos:
    • scripts de instalación, para los cuales no puede confiar en la presencia de otros intérpretes; esto no es para principiantes;
    • funciones para personalizar el shell interactivo (que afectan la invitación, cambiar el directorio, configurar variables de entorno) - tampoco es realmente para principiantes;
    • secuencias de comandos únicas, como la grabación masiva de archivos;
    • archivos make.

Absolutamente primeros pasos

Comencemos: iniciar sesión y cerrar sesión

Asegúrese de saber exactamente cómo iniciar el shell y cómo salir de él.

Si está trabajando en una máquina con Ubuntu instalado, necesita ejecutar programa terminal. Cuando termine, simplemente puede cerrar la ventana.

En MacOS, inicie también Terminal.

Para acceder servidor remoto- use ssh (si tiene MacOS, Ubuntu u otro sistema similar a Unix localmente) o PuTTY (si tiene Windows).

¿Quién soy, dónde estoy?

Ejecute los siguientes comandos:
  • nombre de host: muestra el nombre de la máquina (servidor) en la que se encuentra actualmente;
  • whoami: muestra su inicio de sesión (su nombre en el sistema);
  • tree -d / |less - representación pseudográfica del árbol de directorios en la máquina; salir del desplazamiento -q;
  • pwd: muestra el directorio en el que se encuentra actualmente; en la línea de comando no puedes estar “así”, debes estar en algún directorio (=directorio actual, directorio de trabajo). El directorio de trabajo actual probablemente se muestre en su mensaje.
  • ls: lista de archivos en el directorio actual; ls /home - lista de archivos en el directorio especificado;

Historial de comandos (historial)

Una propiedad importante de una línea de comando completa es el historial de comandos.

Ejecute varios comandos: nombre de host, ls, pwd, whoami. Ahora presione la tecla arriba. El comando anterior aparece en la línea de entrada. Puede utilizar las teclas arriba y abajo para avanzar y retroceder por el historial. Cuando llegue al nombre de host, presione Entrar; el comando se ejecutará nuevamente.

Los comandos del historial no sólo se pueden ejecutar repetidamente, sino también editarlos. Desplácese por el historial hasta el comando ls, agréguele el modificador -l (resulta que ls -l , hay un espacio antes del signo menos, pero no después). Presione Enter; se ejecutará el comando modificado.

Desplazarse por el historial, editar y volver a ejecutar comandos son las acciones más comunes cuando se trabaja en la línea de comandos, así que acostúmbrate.

Copiar y pegar

La línea de comandos está muy centrada en el texto: los comandos son texto, los datos de entrada para la mayoría de los programas estándar son texto y el resultado del trabajo suele ser también texto.

Lo mejor del texto es que se puede copiar y pegar, y esto también se aplica a la línea de comandos.

Pruebe el comando fecha +"%y-%m-%d, %A"
¿Lo ingresó completamente a mano o lo copió del artículo? Asegúrate de poder copiarlo, pegarlo en una terminal y ejecutarlo.

Una vez que haya aprendido a usar man, asegúrese de poder copiar y ejecutar comandos de ejemplo desde la ayuda. Para comprobarlo, busque la sección EJEMPLOS en la ayuda del programa de fechas, copie y ejecute el primer ejemplo proporcionado (por si acaso: el. El signo de dólar no forma parte del comando; esta es una imagen simbólica de un mensaje de entrada).

Cómo copiar exactamente texto desde el terminal y pegarlo en el terminal depende de su sistema y su configuración, así que proporcione instrucciones universales, desafortunadamente, no funcionará. En Ubuntu, intente esto: copiar - simplemente seleccione con el mouse, pegue - botón central ratones. Si no funciona, o si tienes un sistema diferente, busca en Internet o pregunta a amigos más experimentados.

Claves y opciones

Al explorar el historial de comandos, ya descubrió que el comando ls tiene al menos dos opciones. Si lo llamas así, genera una lista simple:

Akira@latitude-e7240: ~/shell-survival-quide> ls Makefile shell-first-steps.md shell-first-steps.pdf shell-survival-quide.md shell-survival-quide.pdf
Si agrega el modificador -l, se muestra información detallada para cada archivo:

Akira@latitude-e7240: ~/shell-survival-quide> ls -l total 332 -rw-rw-r-- 1 akira akira 198 13 de febrero 11:48 Makefile -rw-rw-r-- 1 akira akira 15107 febrero 14 22:26 shell-first-steps.md -rw-rw-r-- 1 akira akira 146226 13 de febrero 11:49 shell-first-steps.pdf -rw-rw-r-- 1 akira akira 16626 13 de febrero 11 :45 shell-survival-quide.md -rw-rw-r-- 1 akira akira 146203 13 de febrero 11:35 shell-survival-quide.pdf
esto es muy situación típica: si se agregan modificadores especiales (teclas, opciones, parámetros) a la llamada del comando, el comportamiento del comando cambia. Compare: árbol / y árbol -d / , nombre de host y nombre de host -f .

Además, los comandos pueden tomar nombres de archivos, nombres de directorios o simplemente cadenas de texto. Intentar:

Ls -ld /home ls -l /home grep root /etc/passwd

hombre

man: ayuda con los comandos y programas disponibles en su máquina, así como con las llamadas al sistema y la biblioteca C estándar.

Pruebe: man grep , man atoi , man chdir , man man .

El desplazamiento hacia adelante y hacia atrás se realiza con los botones “arriba”, “abajo”, “RePág”, “AvPág”, y salir de la vista de ayuda se realiza con el botón q. Buscar texto específico en el artículo de ayuda: presione / (barra diagonal), ingrese el texto para buscar, presione Entrar. Pasar a las siguientes apariciones - tecla n.

Todos los artículos de ayuda están divididos en categorías. Lo más importante:

Es necesario indicar de qué categoría debe mostrarse el certificado en casos de coincidencia de nombres. Por ejemplo, man 3 printf describe una función de la biblioteca estándar de C y man 1 printf describe programa de consola con el mismo nombre.

Puede ver una lista de todos los artículos de ayuda disponibles en su máquina usando el comando man -k. (el punto también es parte de la komada).

menos

Cuando estás en una pequeña ventana de terminal necesitas ver muy texto largo(el contenido de algún archivo, un hombre largo, etc.), utilizan programas especiales de "buscapersonas" (de la palabra página, es decir, volteadores de páginas). El desplazador más popular es el menos popular y es el que le proporciona el desplazamiento cuando lee páginas de manual.

Pruebe y compare el comportamiento:

gato /etc/bash.bashrc gato /etc/bash.bashrc |menos

Puede transferir el archivo al buscapersonas directamente en los parámetros:

Menos /etc/bash.bashrc

Desplazarse hacia arriba y hacia abajo - botones "arriba", "abajo", "Re Pág", "Av Pág", salir - botón q. Busque un texto específico: presione / (barra diagonal), ingrese el texto a buscar, presione Entrar. Pasar a las siguientes apariciones - tecla n. (¿Reconoces las instrucciones sobre el hombre? No es de extrañar, también se usa less para mostrar ayuda.)

Derechos

Cualquier archivo o directorio está asociado con un conjunto de “derechos”: el derecho a leer el archivo, el derecho a escribir en el archivo, el derecho a ejecutar el archivo. Todos los usuarios se dividen en tres categorías: propietario del archivo, grupo de propietarios del archivo y todos los demás usuarios.

Puede ver los permisos de archivos usando ls -l. Por ejemplo:

> ls -l Makefile -rw-r--r-- 1 estudiantes de Akira 198 13 de febrero 11:48 Makefile
Este resultado significa que el propietario (akira) puede leer y escribir el archivo, el grupo (estudiantes) solo puede leer y todos los demás usuarios también pueden leer.

Si recibe un mensaje de permiso denegado mientras trabaja, significa que no tiene derechos suficientes sobre el objeto con el que desea trabajar.

Lea más en man chmod.

STDIN, STDOUT, transportadores (tuberías)

Hay 3 flujos de datos estándar asociados con cada programa en ejecución: flujo de datos de entrada STDIN, flujo de datos de salida STDOUT, flujo de salida de error STDERR.

Ejecute el programa wc, ingrese el texto Buenos días hoy, presione Enter, ingrese el texto buenos días, presione Enter, presione Ctrl+d. El programa wc mostrará estadísticas sobre la cantidad de letras, palabras y líneas en su texto y finalizará:

> wc buen día hoy buen día 2 5 24
En este caso, proporcionó un texto de dos líneas al STDIN del programa y recibió tres números en STDOUT.

Ahora ejecute el comando head -n3 /etc/passwd, debería verse así:

> head -n3 /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x: 2:2:bin:/bin:/usr/sbin/nologin
En este caso, el programa principal no leyó nada de STDIN, sino que escribió tres líneas en STDOUT.

Puedes imaginarlo de esta manera: el programa es una tubería por la que fluye STDIN y sale STDOUT.

La propiedad más importante La línea de comando de Unix permite que los programas "canalizados" se puedan conectar entre sí: la salida (STDOUT) de un programa se puede transferir como datos de entrada (STDIN) a otro programa.

Esta construcción de programas conectados se llama tubería en inglés o transportador o tubería en ruso.

La combinación de programas en una canalización se realiza con el símbolo | (barra vertical)

Ejecute el comando head -n3 /etc/passwd |wc, se verá así:

> cabeza -n3 /etc/contraseña |wc 3 3 117
Lo que sucedió es que el programa principal envió tres líneas de texto a STDOUT, que inmediatamente fue a la entrada del programa wc, que a su vez contó el número de caracteres, palabras y líneas en el texto resultante.

Puede combinar tantos programas como desee en una canalización. Por ejemplo, puede agregar otro programa wc al canal anterior, que contará cuántas palabras y letras había en la salida del primer wc:

> cabeza -n3 /etc/contraseña |wc |wc 1 3 24

Crear pipelines (tuberías) es una tarea muy común cuando se trabaja en la línea de comando. Para ver un ejemplo de cómo se hace esto en la práctica, lea la sección "Creación de un canal unifilar".

redirección de E/S

La salida (STDOUT) de un programa no sólo se puede transferir a otro programa a través de una canalización, sino que también se puede escribir simplemente en un archivo. Esta redirección se realiza usando > (signo mayor que):

Fecha > /tmp/today.txt
Como resultado de ejecutar este comando, el archivo /tmp/today.txt aparecerá en el disco. Ver su contenido desde usando gato/tmp/hoy.txt

Si ya existía un archivo con el mismo nombre, se destruirá su contenido anterior. Si el archivo no existía, se creará. El directorio en el que se crea el archivo debe existir antes de ejecutar el comando.

Si no desea sobrescribir un archivo, sino agregar salida al final, use >> :

Fecha >> /tmp/hoy.txt
Compruebe lo que ahora está escrito en el archivo.

Además, puedes pasar cualquier archivo al programa en lugar de STDIN. Intentar:

WC

Qué hacer cuando algo no está claro

Si encuentra un comportamiento del sistema que no comprende o desea lograr un resultado determinado, pero no sabe exactamente cómo, le aconsejo que proceda en el siguiente orden (por cierto, esto se aplica no solo a los shells):
  • Lo más claramente posible, formule la pregunta o tarea: no hay nada más difícil que resolver "algo que no sé qué";
  • recuerde si ya ha encontrado el mismo problema o uno similar; en este caso, vale la pena probar la solución que funcionó la última vez;
  • lea las páginas de manual apropiadas (si comprende qué páginas de manual son adecuadas en su caso); tal vez encuentre ejemplos adecuados del uso de comandos, las opciones necesarias o enlaces a otros comandos;
  • Piensa: ¿es posible cambiar un poco la tarea? - tal vez, cambiando ligeramente las condiciones, obtenga un problema que ya sabe cómo resolver;
  • haga su pregunta claramente formulada en un motor de búsqueda; tal vez la respuesta se pueda encontrar en Stack Overflow u otros sitios;
Si nada de lo anterior ayuda, busque el consejo de un profesor, un colega experimentado o un amigo. Y no tenga miedo de hacer preguntas "estúpidas": no es una pena no saberlo, es una pena no preguntar.

Si resuelves un problema difícil (por tu cuenta, con la ayuda de Internet u otras personas), escribe tu solución en caso de que a ti o a tus amigos les vuelva a surgir el mismo problema. Puedes grabar de forma sencilla. archivo de texto, en Evernote, publicar en redes sociales.

Métodos de trabajo

Copiar y pegar- de páginas de manual, de artículos sobre StackOverflow, etc. La línea de comando consta de texto, aproveche esto: copie y use comandos de ejemplo, anote los hallazgos exitosos como recuerdo, publíquelos en Twitter y blogs.

Extraiga el comando anterior del historial, agregue otro comando a la canalización, ejecute, repita.Centímetro. Consulte también la sección "Creación de un canal de una sola línea".

Comandos básicos

  • cambiar a otro directorio: cd ;
  • ver el contenido de los archivos: gato, menos, cabeza, cola;
  • manipulación de archivos: cp, mv, rm;
  • ver el contenido del directorio: ls , ls -l , ls -lS ;
  • estructura del directorio: árbol, árbol -d (el directorio se puede pasar como parámetro);
  • buscar archivos: buscar . -nombre ... ;

Analítica

  • baño, baño -l;
  • ordenar -k: ordenar por el campo especificado;
  • sort -n - clasificación numérica;
  • diff - comparación de archivos;
  • grep, grep -v, grep -w, grep "\ " , grep -E - buscar texto;
  • uniq, uniq -c - unicización de cadenas;
  • awk - en la opción awk "(print $1)", para dejar solo el primer campo de cada línea, $1 se puede cambiar a $2, $3, etc.;

Diagnóstico del sistema

  • ps axuww: información sobre los procesos (programas en ejecución) que se ejecutan en la máquina;
  • arriba: visualización interactiva de los procesos que consumen más recursos;
  • df: espacio libre y usado en disco;
  • du - tamaño total de archivos en el directorio (recursivamente con subdirectorios);
  • strace, ktrace: qué sistema llama al proceso;
  • lsof: qué archivos utiliza el proceso;
  • netstat -na, netstat -nap: qué puertos y sockets están abiertos en el sistema.

Es posible que no tenga algunos programas; es necesario instalarlos adicionalmente. Además, algunas opciones de estos programas están disponibles sólo para usuarios privilegiados (root).

Ejecución masiva y semiautomática

Al principio, omita esta sección; necesitará estos comandos y construcciones cuando llegue a las secuencias de comandos de shell simples.
  • prueba - condiciones de verificación;
  • while lectura en bucle línea por línea STDIN;
  • xargs: sustitución de cadenas de STDIN en parámetros del programa especificado;
  • seq - generación de secuencias de números naturales;
  • () - combina la salida de varios comandos;
  • ; - hacer una cosa tras otra;
  • &&: se ejecuta si el primer comando se completa correctamente;
  • || - ejecutar si falla el primer comando;
  • tee: duplica la salida del programa en STDOUT y en un archivo en el disco.

Misceláneas

  • fecha - fecha actual;
  • curl: descarga un documento desde la URL especificada y escribe el resultado en STDOUT;
  • toque - actualizar la fecha de modificación del archivo;
  • matar: envía una señal al proceso;
  • verdadero: no hace nada, devuelve verdadero, útil para organizar bucles eternos;
  • sudo: ejecuta el comando como root "a.

Creando un canal de una sola línea

Veamos un ejemplo de una tarea real: necesitamos eliminar todos los procesos del servidor de tareas 6 que se ejecutan como el usuario actual.

Paso 1.
Comprenda qué programa produce aproximadamente los datos necesarios, aunque no en su forma pura. Para nuestra tarea, vale la pena obtener una lista de todos los procesos del sistema: PD axuww. Lanzamiento.

Paso 2.
Mire los datos recibidos con sus ojos, cree un filtro que elimine algunos de los datos innecesarios. Suele ser grep o grep -v . Utilice la tecla "Arriba" para extraer el comando anterior del historial, asignarle un filtro inventado y ejecutarlo.

Ps axuww |grep `whoami`
- solo procesos del usuario actual.

Paso 3.
Repita el paso 2 hasta que obtenga los datos limpios que necesita.

"
- todos los procesos con el nombre requerido (más, quizás, algunos adicionales como vim task-6-server.c, etc.),

Ps axuww |grep `whoami` | grep "\ " | grep -v vim ps axuww |grep `whoami` | grep "\ " | grep -v vim |grep -v menos
- solo procesos con el nombre requerido

Ps axuww |grep `whoami` | grep "\ " | grep -v vim |grep -v menos |awk "(imprimir $2)"

Pids de los procesos requeridos, paso 3 completado

Paso 4.
Aplicar un manipulador final adecuado. Usando la tecla "Arriba", sacamos el comando anterior del historial y agregamos el procesamiento que completará la solución al problema:

  • |wc -l para contar el número de procesos;
  • >pids para escribir pids en un archivo;
  • |xargs kill -9 procesos de eliminación.

Tareas de entrenamiento

¿Quieres practicar nuevas habilidades? Pruebe las siguientes tareas:
  • obtenga una lista de todos los archivos y directorios en su directorio de inicio;
  • obtener una lista de todos los artículos man de la categoría 2 (llamadas al sistema);
  • cuente cuántas veces aparece la palabra grep en la página de manual del programa grep;
  • cuente cuántos procesos se están ejecutando actualmente como root;
  • encontrar qué comando aparece en el número máximo de categorías de ayuda (hombre);
  • cuente cuántas veces aparece la palabra var en la página ya.ru.
Sugerencia: necesitará find , grep -o , awk "(print $1)" , expresiones regulares en grep , curl -s .

¿Qué estudiar a continuación?

Si te empieza a gustar la línea de comandos, no pares, sigue mejorando tus habilidades.

Aquí hay algunos programas que definitivamente te serán útiles si vives en la línea de comando:

  • encontrar con opciones complejas
  • a propósito
  • localizar
  • Telnet
  • netcat
  • tcpdump
  • sincronización
  • pantalla
  • zgrep, zless
  • visudo
  • crontab-e
  • enviar correo
Además, con el tiempo conviene dominar algún tipo de lenguaje de scripting, por ejemplo, Perl o Python, o incluso ambos.

¿Quién necesita esto?

¿Vale la pena aprender la línea de comandos y los scripts de shell hoy? Definitivamente vale la pena. Daré sólo algunos ejemplos de los requisitos de Facebook para los candidatos que quieran conseguir un trabajo en FB.

El lenguaje de programación Shell tiene varias construcciones que darán flexibilidad a sus programas:

  • Los comentarios le permitirán describir las funciones del programa;
  • "aquí documento" le permite incluir líneas en el shell del programa que serán redirigidas como entrada a algunos de los comandos del shell del programa;
  • El comando de salida le permite finalizar el programa en el punto deseado y utilizar códigos de retorno;
  • Las construcciones de bucle for y while le permiten repetir un grupo de comandos en un bucle;
  • comandos condicionales if y case ejecutan un grupo de comandos si se cumple alguna condición;
  • El comando break le permite salir incondicionalmente de un bucle.

9.3.1. Comentarios

Para colocar comentarios en el programa, utilice el signo #. Si aparece un signo # después de un comando, el comando en sí se ejecuta y el comentario se ignora. Formato de línea de comentarios:

#comentario

9.3.2. "Aquí documento"

"Aquí documento" le permite colocar líneas en un programa de shell que se redirigen como entrada de comando en ese programa. Esta es una forma de proporcionar entrada para un comando en un programa de shell sin utilizar un archivo independiente. La entrada consta de un carácter de redirección.<< и разделителя, который указывает начало и конец строк ввода. В качестве разделителя может использоваться один символ или строка символов. Чаще всего это знак!.

El formato del comando es el siguiente:

Dominio<...líneas de entrada... delimitador

9.3.3. Usando ed en un programa shell

"Aquí el documento" sugiere una forma de utilizar ed en un programa shell. Digamos que desea crear un programa shell que llame al editor ed, realice cambios globales en un archivo, escriba los cambios en el archivo y luego salga de ed. La siguiente pantalla muestra el contenido del programa ch.text que realiza estas tareas:

$ gato ch.texto echo Escriba el nombre del archivo read file1 echo Escriba el texto exacto que desea cambiar.<

leer texto_antiguo echo Escriba exactamente el nuevo texto para reemplazar el anterior.

leer new_text ed - $file1

Tenga en cuenta el signo - (menos) en el comando ed. Esta opción evita que el contador de caracteres se imprima en la pantalla. También tenga en cuenta el formato del comando ed para reemplazo global:
G/$texto_antiguo/s//$texto_nuevo/g
El programa utiliza 3 variables: archivo1, texto_antiguo, texto_nuevo. Cuando se ejecuta, este programa utiliza el comando de lectura para obtener los valores de estas variables. Estas variables contienen la siguiente información:
archivo: nombre del archivo que se editará;

old_text: texto que se cambiará;

new_text - texto nuevo. Las variables se introducen en el programa; aquí el documento redirige el comando de reemplazo global, el comando de escritura y el comando de finalización al comando ed. Ejecute el programa ch.text. Obtenga la siguiente pantalla: $ch.texto Escriba la nota del nombre del archivo Escriba el texto exacto que desea cambiar. Querido Juan: $

Escriba exactamente el nuevo texto para reemplazar el anterior.

A lo que pueda corresponder:

$ nota de gato

Después de ejecutar un comando de forma interactiva, puede ver el código de salida cuando escribe:

Considere el siguiente ejemplo:

$ cat hola Este es el archivo hola.

$eco$?

0 $ gato hola gato: ¿no se puede abrir hola $ eco $?$2 En el primer caso, el archivo hola existe en su directorio y tiene permiso de lectura. Usando el comando cat puedes imprimir el contenido de un archivo. El resultado del comando cat es el código de retorno 0, que obtendrá especificando el parámetro $? En el segundo caso, el archivo no existe o no tienes permiso de lectura. El comando cat imprime un mensaje de diagnóstico y devuelve el código 2. programa shell

sale normalmente cuando termina

último comando

en el archivo. Sin embargo, puede utilizar el comando de salida para finalizar el programa. Más importante aún, puede utilizar el comando de salida para obtener los códigos de retorno del programa Shell.

9.3.5. Ciclos

Las instrucciones de bucle for y while le permiten ejecutar un comando o secuencia de comandos varias veces. 9.3.5.1. para declaración La declaración for ejecuta una secuencia de comandos para cada elemento de la lista. Tiene el formato: Para variables en una_lista_de_valores hacer comando_1

comando_2

.

.

.

último comando hecho Para cada iteración del bucle, el siguiente elemento de la lista se asigna a la variable proporcionada en la declaración for. Se puede hacer referencia a esta variable en cualquier lugar de los comandos dentro de una declaración do. Al construir cada sección de comandos, debe asegurarse de que para cada hacer haya un hecho correspondiente al final del ciclo.

La variable puede tener cualquier nombre. Por ejemplo, si su variable se llama var, entonces una referencia a $var en la lista de comandos hará que el valor esté disponible. Si se omite el operador in, entonces el valor de var será el conjunto de argumentos especificados en el comando y disponibles en el parámetro especial $*. La lista de comandos entre las palabras clave do y done se ejecutará para cada valor.

Cuando se ejecutan los comandos para el último elemento de la lista, el programa ejecutará la línea siguiente. Para variables hacer La declaración for ejecuta una secuencia de comandos para cada elemento de la lista. Tiene el formato: Para variables hacer comando_1

9.3.5.2. mientras declaración

Operador mientras bucle

Después de hacer algunas adiciones, obtenemos el siguiente programa:

Operador echo Por favor escriba el nombre de cada persona y luego un eco por favor terminar el lista de nombres con un<^d>mientras lee x haz echo $x>>xfile hecho echo xfile contiene la siguiente nombres: gato xfile $

Tenga en cuenta que una vez que se completa el ciclo, el programa ejecuta los siguientes comandos.

Los dos primeros comandos de eco usan caracteres especiales, por lo que debes usar comillas para escapar del significado especial. La siguiente pantalla muestra el resultado de enter.name:

$ingrese.nombre Por favor escriba el nombre de cada persona y luego un Por favor finalice la lista de nombres con un<^d>María Lou janice <^d>xfile contiene los siguientes nombres: Mary Lou Janice $

Una vez que se complete el ciclo, el programa imprimirá todos los nombres contenidos en el xfile.

9.3.6. Usando /dev/null

El sistema de archivos tiene un archivo /dev/null donde puede almacenar resultados no deseados. Por ejemplo, si simplemente ingresa el comando who, el sistema responderá quién está trabajando en el sistema. Si redirige la salida de este comando a /dev/null:

Quién > /dev/null

entonces no obtendrás una respuesta.

9.3.7. Declaraciones condicionales

si... entonces declaración

El comando if le dice al programa shell que ejecute la secuencia de comandos después de que el último comando en la lista de comandos de la declaración if se haya completado con éxito. Si las construcciones terminan con la palabra clave fi.

El formato general de la construcción if es:

Si Para variables hacer entonces Para variables hacer fi

Por ejemplo, el programa shell de búsqueda demuestra el uso de la construcción if... then. El programa de búsqueda utiliza el comando grep para buscar una palabra en un archivo. Si grep tiene éxito, el programa muestra la palabra encontrada. La pantalla se verá así:

$ búsqueda de gatos echo Escriba la palabra y el nombre del archivo.

lea el archivo de Word si grep $palabra $archivo entonces echo $palabra está en $archivo fi $

Este programa muestra el resultado del comando grep. Si desea almacenar la respuesta del sistema al comando grep en su programa, use el archivo /dev/null, cambiando la línea de comando if a lo siguiente:

Si grep $palabra $archivo > /dev/null

Ahora ejecute el comando de búsqueda. Solo responderá con el mensaje especificado después del comando echo.

Si Para variables hacer La construcción if... then... else puede ejecutar un conjunto alternativo de comandos después de else si la secuencia if es falsa. El formato de esta construcción es el siguiente: Para variables hacer .linento Para variables hacer fi

Con esta construcción, puede mejorar el programa de búsqueda para que le indique tanto la palabra encontrada como la palabra no encontrada. En este caso, el programa de búsqueda se verá así:

$ búsqueda de gatos echo Escriba la palabra y el nombre del archivo.

lea el archivo de Word si grep $word $file > /dev/null entonces echo $word está en $file else echo $word NO está en $file fi $

comando de prueba

El comando de prueba se utiliza para organizar un bucle. Prueba ciertas condiciones para determinar la verdad y es útil para organizar estructuras condicionales. Si la condición es verdadera, el ciclo continuará. Si la condición es falsa, el ciclo finalizará y se ejecutará el siguiente comando. Algunos ejemplos de uso del comando de prueba: Prueba -r archivo Es verdadero si el archivo existe y es legible; prueba -w archivo Es verdadero si el archivo existe y se puede escribir; prueba -x archivo Es verdadero si el archivo existe y es ejecutable;

prueba -s archivo

Es verdadero si el archivo existe y tiene al menos un carácter; prueba var1 -eq var2 verdadero si var1 es igual a var2; prueba var1 -ne var2

Es cierto si var1 no es igual a var2.

Ejemplo. Creemos un programa shell que mueva todos los archivos ejecutables desde el directorio actual a su directorio bin. Para hacer esto, usaremos el comando test -x para seleccionar archivos ejecutables. El programa mv.file se verá así:

$ gato mv.archivo escriba echo en la ruta del directorio ruta de lectura para archivo hacer si prueba -x $archivo entonces mv $archivo $ruta/$archivo fi hecho $ 1La construcción case...esac le permite seleccionar uno de varios patrones y luego ejecutar una lista de comandos para ese patrón. La expresión del patrón debe comenzar con la palabra clave in y se debe colocar un paréntesis derecho después del último carácter de cada patrón. La secuencia de comandos para cada patrón termina con dos caracteres;;. La construcción case debe terminar con la palabra clave esac. ;;El formato general de la construcción del caso es: palabra caso en ;;patrón1) palabra caso en ;; *)palabra caso en ;;línea de comando

.

Si no se encuentra la primera plantilla, se realiza la transición a la segunda plantilla. Si se encuentra algún patrón, el programa no considera los patrones restantes, sino que pasa al comando que sigue a esac. El * se utiliza como patrón para buscar cualquier palabra y, por lo tanto, le brinda un conjunto de comandos que se ejecutarán si no se encuentra ningún otro patrón. Por lo tanto, el patrón de asterisco (*) se coloca como último patrón en la construcción del caso para que los demás patrones se verifiquen primero. Esto le ayudará a detectar entradas incorrectas e inesperadas.

Las plantillas pueden utilizar metacaracteres *, ?, . Esto proporciona flexibilidad al programa.

Veamos un ejemplo. El programa set.term establece la variable TERM según el tipo de terminal que esté utilizando. Se utiliza la siguiente línea de comando:

TERM=nombre_terminal

La plantilla * es la última en la lista de plantillas. Emite un mensaje de advertencia de que no hay ningún patrón coincidente para el tipo de terminal especificado y le permite completar la construcción del caso.

$ gato conjunto.term echo Si tiene un TTY 4420 tipo en 4420 echo Si tiene un TTY 5410 tipo en 5410 echo Si tiene un TTY 5420 tipo en 5420 lea término caso término en 4420) TERM-T4 ;;

5410) TÉRMINO-T5 ;;

5420) TÉRMINO-T7 ;;

*) echo no es un tipo de terminal correcto ;;

$ gato conjunto.term esac export TERM echo fin del programa $

9.3.8. Transferencia incondicional de control

El comando break detiene incondicionalmente la ejecución de cualquier bucle en el que se encuentre y pasa el control al comando que sigue a las palabras clave done, fi o esac.

En el ejemplo anterior del programa set.term, podría usar el comando break en lugar de echo para salir del programa, como en el siguiente ejemplo:echo Si tiene un TTY 4420 tipo en 4420 echo Si tiene un TTY 5410 tipo en 5410 echo Si tiene un TTY 5420 tipo en 5420 lea término caso término en 4420) TERM-T4 ;;5410) TÉRMINO-T5 ;;5420) TÉRMINO-T7 ;;

*) romper ;; esac export TERM echo fin del programa $

El comando continuar hará que el programa pase inmediatamente a la siguiente iteración del bucle while o for sin ejecutar los comandos restantes en el bucle.MOSCÚ 2007

Taller de laboratorio del curso: “Sistema operativo : Rojo

Sombrero

La ejecución de comandos individuales en el shell no siempre es una forma eficaz de trabajar con el shell SHELL. Muy a menudo, cuando se trabaja con el sistema operativo Linux, es necesario realizar la misma secuencia de acciones todos los meses, todas las semanas, todos los días y, a veces, varias veces al día. Por ejemplo, digamos que trabaja para una empresa como probador de software (Test Manager). Todos los días es necesario realizar un conjunto de acciones en el shell de comandos de Linux, a saber: montar un dispositivo de CD-ROM; copiar toda la información a una carpeta, por ejemplo, /opt/program en su disco duro; desmontaje de CD-ROM; leer el archivo Léame de esta carpeta; instalando el programa desde disco duro desde la carpeta /opt/programa; creando un nuevo archivo de informe en el directorio /home/user/report_program y eliminando todo el contenido de la distribución del disco duro. Y esto a pesar de que su trabajo principal es probar el software para identificar errores. La tarea a primera vista es simple, pero es un inconveniente realizar tales acciones varias veces al día, a pesar de que también estás haciendo otras cosas. O, por ejemplo, trabaja en una empresa como administrador de sistemas y da servicio a unos 50 ordenadores. Todos los días es necesario copiar el mismo archivo a todas las computadoras con instrucciones para el día actual del director de la empresa para todos los subordinados. Además, tus tareas también incluyen, al final de la jornada laboral, guardar todos los datos de cada usuario en el servidor común de la empresa desde los ordenadores personales de los subordinados. La tarea también es sencilla a primera vista, pero escribir comandos en un intérprete de comandos para 50 ordenadores llevará mucho tiempo. ¿Qué pasa si, además, cometes errores al escribir, por ejemplo, por cansancio? Los datos son muy importantes para el director y su propietario, y no puedes perderlos. Pero esto todavía es pasos simples. ¿Imagina que los nombres de los archivos de informes, los nombres de las carpetas de datos y los nombres de las computadoras cambiarán cada vez? ¿Qué hacer entonces? Sólo hay una salida: escribir archivo de secuencia de comandos , es decir. cree un archivo de texto en el que necesite describir la secuencia completa de comandos con rutas, opciones, argumentos, expresiones, acciones, etc. para ejecutar un script específico. Por ejemplo, copia de seguridad de datos. Después de ingresar comandos en un archivo de secuencia de comandos de texto, el archivo se vuelve ejecutable o se ejecutan las declaraciones de ejecución del intérprete de comandos especiales. El uso de archivos de script es especialmente eficaz si necesita ejecutar con mucha frecuencia una secuencia de gran número comandos También es una herramienta eficaz si la ejecución de comandos posteriores depende de los resultados de los comandos anteriores. Al utilizar archivos de script, también puede utilizar expresiones aritméticas y lógicas y crear bucles que ejecuten repetidamente un grupo de comandos de Linux.

Creación de archivos de script. Las secuencias de comandos son un conjunto secuencial de comandos, declaraciones de shell y algunos otros símbolos en un archivo de texto. Los archivos de script también se denominan scripts y los intérpretes de comandos se denominan SHELL. Debido a que hoy en día existen diferentes intérpretes de comandos, escribir un archivo de script utilizando símbolos adicionales, por ejemplo, metasímbolos, junto con los comandos no debe contradecir las reglas de sintaxis del intérprete de comandos seleccionado en el que se supone que se ejecutará este script. El proceso de escribir dichos archivos se llama programación SHELL. Veamos el proceso de programación usando el intérprete BASH como ejemplo. Por lo tanto, es posible que los scripts y las reglas de scripting de esta práctica de laboratorio no sean portátiles para otros intérpretes, como C Shell o TC Shell.

Subsecuencia #!. La redacción de cualquier guión comienza con su pertenencia a uno de los intérpretes de comandos. La primera línea del script suele contener la secuencia #! , que le dice al sistema qué intérprete debe ejecutar los comandos en el script dado. Si el primer carácter es un espacio, se considera que el script está escrito en BASH o PDKSH. Si el script comienza solo con el símbolo #, entonces se requiere TC Shell para ejecutarlo. Si el carácter # va seguido de un carácter !, el núcleo iniciará el intérprete cuya ruta se indica más adelante en esta línea. Por ejemplo, para BASH sería próxima entrada: #!/bin/sh . Un espacio o un solo carácter # al comienzo de un script es suficiente para los intérpretes de BASH Shell y TC Shell solo si van a leer su script. Para que un intérprete reconozca los guiones de otro, es necesario incluir los caracteres #! , seguido de la ruta del programa de interpretación. Luego, cuando se llama al script, el intérprete actual finalizará, se cargará un tipo diferente de script y luego se ejecutará el script. Se recomienda iniciar siempre todos los scripts con la secuencia #! . Además, las líneas que comienzan con el símbolo # se pueden utilizar para comentar las acciones del usuario en el script. Cuando el shell encuentra un símbolo #, ignora esta línea. Cada comentario debe terminar con un carácter de final de línea. El uso de comentarios es señal de buenos modales.

Ampliación y ejecución de scripts. Normalmente, los archivos de script no sólo tienen nombres, sino también extensiones. La mayoría de las veces, se utiliza una combinación de letras como extensiones. sh De la palabra latina concha. Con esta extensión, sin abrir el archivo, queda inmediatamente claro que se trata de un script de shell, ya que nuevamente nos queda claro que el archivo con la extensión . do lo más probable es que sea un archivo de entrada de idiomas alto nivel C y C++. Después de escribir el contenido del archivo, el archivo se guarda. Hay dos formas de ejecutar un archivo: hacerlo ejecutable usando el comando chmod o ejecutarlo usando operadores de shell especiales: sh y. Normalmente, los usuarios configuran el archivo de script en valores octales de 750 o 550. En el siguiente ejemplo, haremos que el script script.sh sea ejecutable usando el comando chmod y lo ejecutaremos desde el directorio actual en segundo plano.

chmod u+x script.sh

./ script.sh &

Ahora devolvamos los atributos anteriores al archivo y lancemos para su ejecución usando la declaración BASH.

chmod u-x script.sh

sh script.sh&

Equipo eco . Además de la lista de comandos estándar de Linux, lo más simple que puede usar en un script es mostrar comentarios de texto al usuario usando el comando echo. Por ejemplo, este comando se puede utilizar para invitar al usuario a realizar alguna acción o para saludar al usuario. El siguiente ejemplo utiliza echo para mostrar un saludo.

eco "¡Buenas tardes!"

Equipoleer . Cuando crea scripts, también puede utilizar variables y scripts escritos para otros intérpretes y comandos. El comando de lectura sirve como un comando para solicitar información al usuario. Se combina con una sugerencia para el usuario, que lo invita a ingresar la información requerida. A continuación se muestra un ejemplo del uso de lectura.

eco “Ingrese su nombre:”

leer su _ nombre

eco “ Amable día "Su nombre"!

Este script es más complicado que el anterior. Esto utiliza la variable your_name, cuyo valor luego se aplica junto con el texto.

Usando variables. Al igual que los lenguajes de programación, también puedes usar variables en el shell; puedes asignar valores a las variables usando el operador de asignación igual a “="”. Primero, ingrese el nombre de la variable, luego el signo “=" sin espacio, luego el valor de la variable sin espacio. El nombre de la variable puede constar de cualquier número de caracteres alfabéticos, incluido el carácter de subrayado. El nombre puede contener números, pero no debe comenzar con un número. Todos los demás caracteres (en particular, el signo de exclamación, el signo comercial y el espacio) no deben incluirse en el nombre. El intérprete reserva dichos símbolos para fines especiales. Como consecuencia, el nombre sólo puede constar de una palabra, porque al analizar comandos, el intérprete trata el espacio como un delimitador entre los nombres de los comandos y los argumentos. El valor de una variable puede constar de cualquier secuencia de caracteres. En el siguiente ejemplo, asignaremos el valor “www123yyy” a la variable “ppp”.

ppp =” www 123 yyy

Si está utilizando un valor de cadena como valor de una variable, utilice comillas dobles. Una vez que se asigna un valor, puede usar el nombre de la variable para hacer referencia a ese valor, por ejemplo, usarlo como argumento para comandos de secuencia de comandos. Se puede hacer referencia al valor de una variable por su nombre, que está precedido por el operador $. El signo de dólar es un operador especial que utiliza el nombre de una variable para referirse a su valor, es decir, para evaluarla realmente. Ahora, usando el conocido comando echo y la variable "ppp", puede mostrar el valor de esta variable.

eco $ppp

www123yyy

Argumentos de la línea de comando. En un script, al igual que en los comandos de Linux, puedes usar argumentos. Un argumento en un script se indica mediante el operador $ seguido de un número de posición en la línea de comando. La numeración de parámetros comienza con uno y termina con nueve. El primer parámetro se establece en $1, el segundo en $2, etc. El argumento $0 está reservado para el nombre del script de shell, que es la primera palabra en la línea de comando. Por defecto, es posible configurar 9 variables de $1 a $9. Si ingresa varios argumentos, puede hacer referencia a cada uno por separado por su número. El siguiente ejemplo ingresa tres argumentos en la línea de comando. Primero creemos un script de argumentos con argumentos y luego ejecutémoslo.

Tenga en cuenta que si necesita utilizar argumentos de varias palabras, debe encerrarlos entre comillas dobles en la línea de comando. A veces es necesario especificar el número exacto de argumentos en un script, esto se puede hacer usando el argumento $#. La opción $* le permite especificar todos los argumentos en la línea de comando.

Variableexportar. A veces, para diferentes archivos de script, es necesario utilizar una determinada variable que ya se ha definido. Las variables que usted define en el shell son locales. En cierto sentido, dicha variable pertenece a su intérprete. No puede definir directamente una variable para otro intérprete, pero puede exportar una definición de variable de un intérprete a otro usando el comando exportar. El comando de exportación contiene una instrucción para el sistema según la cual se definirá una copia de esta variable para cada shell recién creado. Cada nuevo shell tendrá su propia copia de la variable exportada. En el siguiente ejemplo, definiremos la variable "rrr" y la exportaremos para otros intérpretes usando el comando exportar.

Operaciones aritméticas - comandodejar . El comando let es un comando de shell BASH que realiza operaciones con valores aritméticos. Con este comando podrás comparar o realizar valores numéricos sobre ellos. operaciones aritméticas, como la suma o la multiplicación. Formato de comando: let valor1 operador valor2. Pongamos un ejemplo.

$ deja 2*5

10

Las expresiones aritméticas que utilizan el operador let también pueden incluir operadores de asignación. El siguiente ejemplo asigna el resultado de multiplicar dos números a la variable total.

$ sea “total=2*5”

$ eco $total

10

$

Los operadores de comparación se utilizan a menudo para comparar valores numéricos en construcciones de control como bucles y ramas condicionales. En el siguiente ejemplo, los comandos del script file1 muestran la palabra "¡Hola!" cuatro veces. En este caso, el operador let "ttt" se utiliza para controlar la salida del bucle.<= 4", а для увеличения переменной цикла again на единицу - оператор let "ttt = ttt + 1". Обратите внимание на то, что при изменении переменной again ее вычислять не требуется.

Archivo1

ttt=l

mientras deja "ttt<= 4"

hacer

echo $ttt ¡Hola!

sea ​​"ttt = ttt + 1"

hecho

Ejecutando el script:

$archivo1

¡Hola!

¡Hola!

¡Hola!

Además, también puedes utilizar otros operadores aritméticos. La Tabla 1 enumera los operadores aritméticos y de comparación de Bash Shell.

Tabla 1: declaraciones de shell BASH

Operadores aritméticos

Funciones

Multiplicación

Suma

Sustracción

División con resto

Operadores de comparación

Funciones

Más que

Menos que

Mayor o igual a

Menor o igual a

Igualdad en las expresiones

Igualdad en el comando let

No igual

Y lógico

O lógico

NO lógico

Estructuras de control. Las construcciones de control están diseñadas para controlar la ejecución de comandos de script de shell. Estas construcciones le permiten organizar la ejecución repetida de una determinada secuencia de comandos o seleccionar comandos para ejecutar que sean necesarios en una situación particular. La estructura de control consta de dos componentes principales: operaciones de verificación y comandos. El resultado de una comparación (probar una condición) se devuelve como verdadero o falso y luego se ejecutan comandos específicos en función del resultado. Hay dos tipos de estructuras de control: cíclico (ciclos) Y condicional (nosotros)lovia). Una construcción cíclica se usa para ejecutar comandos repetidamente, mientras que una construcción condicional se usa para ejecutar una secuencia. dominio., que satisface ciertas condiciones. El intérprete de shell BASH le permite utilizar tres construcciones de bucle, while, for y for-in, y dos construcciones condicionales, if y case.

Las construcciones de control while y if son construcciones de propósito general que se usan comúnmente para resolver problemas como cálculos iterativos y pruebas de diversas condiciones. Los constructos de control caso y para se centran en una gama más reducida de tareas. La construcción de caso es un operador multivariado y es un caso especial del operador condicional if. Este diseño se utiliza a menudo al crear menús. La construcción for es un bucle que procesa toda la información una vez para cada valor incluido en la lista hasta encontrar el final de la lista.

Además de comparar valores o variables, las construcciones de control if y while se pueden utilizar para probar si un comando del sistema Linux tuvo éxito o falló. Recuerde que en Linux, cada comando ejecutado devuelve un código de salida. Si el comando fue exitoso, su código de salida es 0. Si por alguna razón el comando no se ejecutó exitosamente, el código de salida será algún valor positivo que indique el tipo de error. Las construcciones de control if y while le permiten verificar si el código de salida era igual a 0 o algún otro valor. Si el código de salida es cero, la ejecución del comando fue exitosa y se completará la construcción de control if o while.

Equipoprueba . Puede comparar valores no solo usando construcciones de control condicional, sino también usando el comando de prueba. Al comparar dos valores, la prueba devuelve 0 si la comparación es exitosa. El comando de prueba le permite comparar números enteros, cadenas e incluso realizar operaciones lógicas. Junto con el comando de prueba, utilice opciones que especifiquen el tipo de comparación. En la Tabla 2 se proporciona una lista completa de opciones.

Tabla 2. Operaciones realizadas por el comando de prueba del shell BASH

Comparación de números enteros

Función

Más que

Menos que

Más que igual

menos que igual

No igual

Comparación de cadenas

Función

Comprobando una cadena vacía

Comprobando la presencia de un valor de cadena

Prueba de igualdad de cadenas

Comprobando cadenas en busca de desigualdad

Comprobando una cadena que consta de ceros

Operaciones lógicas

Función

Y lógico

O lógico

NO lógico

Comprobando archivos

Función

Establecer la existencia de un fichero y su regularidad

Comprueba si el archivo está vacío.

Comprobando la capacidad de leer desde un archivo

Comprobar si se puede escribir o modificar un archivo

Comprueba si el archivo es ejecutable.

Comprueba si el nombre del archivo es un nombre de directorio

Comprueba si el nombre del archivo es un enlace simbólico

Comprueba si el nombre del archivo indica un dispositivo orientado a bytes

Comprueba si el nombre indica un dispositivo orientado a bloques

El comando de prueba tiene la siguiente sintaxis:

valor de prueba-valor de opción

cadena de prueba = cadena

El siguiente ejemplo mostrará un ejemplo del uso del comando de prueba. Comparemos valores enteros; para esto usamos la opción de igualdad –eq. Para comprobar el resultado de la operación de comparación, utilizamos el código de finalización del último comando ejecutado, test, que se almacena en la variable $? caparazón del intérprete.

$ nene = 4

$prueba$ nene -eq 7

$eco$?

1

El comando test $tot –eq 7 también se puede escribir de otra forma:

$ [ $tot –eq 7 ]

Construcciones condicionales:si, si-si no, elif, caso . El intérprete de shell BASH incluye varias construcciones de control condicional (Tabla 3) que le permiten seleccionar comandos de Linux específicos para ejecutar. Muchas de estas construcciones se parecen a las construcciones de control condicional en los lenguajes de programación, pero existen algunas diferencias.

Tabla 3 – Estructuras de control de intérpretesintentoCaparazón

Estructuras de control condicional

Función

si comando entonces comando fi

La construcción if hace que se ejecute una acción si el resultado de la prueba es verdadero

si comando entonces comando else comando fi

La construcción if-else hace que se ejecute una acción si el código de finalización del comando que se está probando es verdadero; de lo contrario, se ejecuta la acción else.

si comando entonces comando elif comando entonces comando else fi comando

La construcción elif le permite anidar cláusulas if, permitiéndole elegir entre muchas opciones; si la condición probada por la primera construcción si es verdadera, los comandos proporcionados en ella se ejecutan y el control no se transfiere a la siguiente construcción elif

cadena de mayúsculas y minúsculas en patrón) comando;; esac

La construcción de caso compara un valor de cadena con uno de varios patrones. Cuando se encuentra una coincidencia, se ejecutan los comandos que coinciden con este patrón.

comando && comando

La operación lógica AND devuelve 0 (verdadero) si ambas instrucciones devuelven 0; si uno de los comandos no regresa valor nulo, el resultado de la operación AND es "falso" y esta operación devuelve un valor distinto de cero

equipo | | equipo

Una operación lógica OR que devuelve 0 (verdadero) si uno o ambos comandos devuelven 0 (verdadero); Si ambos comandos devuelven un valor distinto de cero, entonces el resultado de la operación OR es falso y la operación devuelve un valor distinto de cero.

Equipo

Operación lógica NO, invierte el código de finalización del comando

mientras que el comando hace los comandos hechos

La construcción while realiza la acción hasta que el comando de prueba devuelve verdadero.

hasta que el comando haga los comandos terminados

La construcción hasta realiza la acción hasta que el comando de prueba devuelve falso.

Estructuras de control cíclico

Función mientras, hasta, para, para-en, seleccione

para la variable en la lista de valores, haga el comando hecho

La construcción for-in está diseñada para procesar una lista de valores. A la variable se le asignan valores secuencialmente de la lista

para variable do de comando hecho

La construcción for está diseñada para procesar argumentos de script de forma secuencial. A la variable se le asigna el valor de cada argumento de forma secuencial.

seleccione la línea en la lista de elementos y haga el comando hecho

La construcción de selección crea un menú basado en los elementos de la lista dada y luego ejecuta el comando especificado (generalmente un comando de caso)

Construcción condicionalsi - entonces . La construcción condicional if establece una condición para la ejecución de un comando. Esta condición es el código de salida de un comando de Linux específico. Si el comando se completó correctamente (es decir, el código de salida es 0), se ejecutan los comandos dentro de la instrucción if. Si el código de salida es diferente de 0, entonces los comandos dentro de la construcción if no se ejecutarán. A veces es necesario elegir una de dos opciones, dependiendo de cómo se ejecutó el comando de Linux. La palabra clave else en la cláusula if le permite elegir una de dos opciones. Aquí está la sintaxis del comando if-then-else.

Como se mencionó anteriormente, para construir algoritmos arbitrarios es necesario contar con operadores de verificación de condición. Caparazón intento apoya declaraciones de selección sientoncesmás y caso, así como operadores de bucle para,mientras, hasta, convirtiéndolo en un poderoso lenguaje de programación.

5.8.1 Operadores si Y prueba(o )

La construcción del operador condicional en una forma ligeramente simplificada se ve así:

si lista1 entonces lista2 si no lista3 fi

Dónde lista1, lista2 y lista3 son secuencias de comandos separados por comas y que terminan con un punto y coma o un carácter de nueva línea. Además, estas secuencias se pueden encerrar entre llaves: (lista).

último comando si Comprueba el valor devuelto por los comandos de lista1. Si hay varios comandos en esta lista, se verifica el valor devuelto por el último comando de la lista. Si este valor es 0, entonces los comandos de lista2; si este valor no es cero, los comandos de lista3. El valor devuelto por dicho operador compuesto. si, es el mismo que el valor producido por el último comando de la secuencia que se ejecuta.

Formato de comando completo si tiene la forma:

si lista entonces lista [ elif lista entonces lista ] ... [ más lista ] fi

(aquí los corchetes sólo significan que lo que contienen no necesariamente está presente en el operador).

Como expresión que viene inmediatamente después si o elif, un comando de uso frecuente prueba, que también puede indicarse entre corchetes. Equipo prueba evalúa alguna expresión y devuelve 0 si la expresión es verdadera y 1 en caso contrario. La expresión se pasa al programa. prueba como argumento. en lugar de escribir

expresión de prueba,

Puede encerrar la expresión entre corchetes:

[expresión].

Por favor tenga en cuenta que prueba y [ son dos nombres del mismo programa, no una conversión mágica realizada por el shell intento(solo la sintaxis [ requiere que se incluya un paréntesis de cierre). Tenga en cuenta también que en lugar de prueba en diseño si Se puede utilizar cualquier programa.

En conclusión, damos un ejemplo del uso del operador. si:

si [-e modotexto2.htm]; entonces

ls modo texto*

demás

persona con discapacidad

Sobre el operador prueba(o […]) necesitamos tener una conversación especial.

5.8.2 Operador prueba y condicionales

Expresiones condicionales utilizadas en la declaración. prueba, se construyen sobre la base de la verificación de atributos de archivos, comparaciones de cadenas y comparaciones aritméticas ordinarias. Las expresiones complejas se construyen a partir de las siguientes operaciones unarias o binarias (“bloques de construcción elementales”):

    un archivo

Verdadero si existe un archivo llamado file.

    archivo B

cierto si archivo existe y es un archivo de dispositivo de bloque especial.

    archivo C

cierto si archivo existe y es un archivo de dispositivo de caracteres especiales.

    archivo D

cierto si archivo existe y es un directorio.

    archivo e

Verdadero si el archivo llamado archivo existe.

    archivo F

Verdadero si el archivo llamado archivo existe y es un archivo normal.

    archivo G

Verdadero si el archivo llamado archivo existe y su bit de cambio de grupo está establecido.

    Archivo H o archivo -L

Verdadero si el archivo llamado archivo existe y es un vínculo simbólico.

    archivo K

Verdadero si el archivo llamado archivo existe y su bit "pegajoso" está establecido.

    archivo P

Verdadero si el archivo llamado archivo existe y es tubería con nombre(FIFO).

    archivo R

Verdadero si el archivo llamado archivo existe y tiene conjunto de permisos de lectura

    archivo S

Verdadero si el archivo llamado archivo existe y su tamaño es mayor que cero.

    tfd

Verdadero si el descriptor del archivo fd está abierto y apunta a la terminal.

    archivo U

Verdadero si el archivo llamado archivo existe y su bit de cambio de usuario está establecido.

    archivo W

Verdadero si el archivo llamado archivo existe y tiene permisos de escritura establecidos.

    archivo x

Verdadero si el archivo llamado archivo existe y es ejecutable.

    Oh archivo

Verdadero si el archivo llamado archivo existe y es propiedad del usuario señalado por la identificación de usuario efectiva.

    archivo G

Verdadero si el archivo llamado archivo existe y pertenece al grupo identificado por el ID de grupo efectivo.

    archivo S

Verdadero si el archivo llamado archivo existe y es un enchufe.

    N archivo

Verdadero si el archivo llamado archivo existe y ha cambiado desde la última vez que se leyó.

    archivo1 -nt archivo2

Verdadero si el archivo archivo1 tiene un tiempo de modificación posterior al archivo2.

    archivo1 -ot archivo2

Verdadero si el archivo archivo1 mayor que archivo2.

    archivo1 -ef archivo2

Verdadero si los archivos archivo1 Y archivo2tener el mismo dispositivo y números de inodo(inodo).

    O nombre de opción

Verdadero si la opción Shell está habilitada nombreopt. Para obtener una explicación, consulte la página de manual de bash.

    cuerda Z

Verdadero si la longitud de la cadena es cero.

    N cadena

Verdadero si la longitud de la cadena no es cero.

    cadena1 == cadena2

Verdadero si las cadenas coinciden. En lugar de == se puede utilizar = .

    cadena1 !== cadena2

Verdadero si las cadenas no coinciden.

    cadena1< string2

Verdadero si la línea cadena1 precede lexicográficamente a la cadena cadena2(para la ubicación actual).

    cadena1 > cadena2

Verdadero si la línea cadena1 lexicográficamente viene después de la línea cadena2(para la ubicación actual).

    arg1 OP arg2

Aquí OP- oh entonces una de las operaciones de comparación aritmética: -eq(igual), -nordeste(no igual) -lt(menos que) -le(menor o igual a) -gt(más), -ge(mayor o igual que). Se pueden utilizar números enteros positivos o negativos como argumentos.

A partir de estas expresiones condicionales elementales puedes construir expresiones condicionales tan complejas como quieras usando las operaciones lógicas habituales de NEGACIÓN, Y y O:

    !(expresión)

Operador de negación booleano.

    expresión1 -una expresión2

operador booleano Y(Y). Verdadero si ambas expresiones son verdaderas.

    expresión1 -o expresión2

operador booleano O(O). Verdadero si alguna de las dos expresiones es verdadera.

Lo mismo expresiones condicionales También se utilizan en operadores. mientras Y hasta, que veremos a continuación.

5.8.3 Operador caso

Formato de operador caso es:

palabra caso en [ [(] patrón [ | patrón ] ...) lista ;; ]...esac

Equipo caso primero produce expansión de palabras palabra, e intenta hacer coincidir el resultado con cada una de las muestras. patrón uno por uno. Después de encontrar la primera coincidencia, no se realizan más comprobaciones; se ejecuta la lista de comandos que siguen el patrón con el que se encontró la coincidencia. El valor devuelto por el operador es 0 si no se encontraron coincidencias de patrón. De lo contrario, se devuelve el valor producido por el último comando de la lista correspondiente.

El siguiente ejemplo de uso de la declaración case está tomado del script del sistema /etc/rc.d/rc.sysinit.

caso "$UTC" en

si|verdadero)

RELOJFLAGS="$RELOJFLAGS -u";

RELOJDEF="$RELOJDEF (utc)";

no|falso)

CLOCKFLAGS="$CLOCKFLAGS --hora local";

CLOCKDEF="$CLOCKDEF (hora local)";

esac

Si la variable se evalúa como sí o verdadero, entonces se ejecutará el primer par de comandos, y si su valor es no o falso, se ejecutará el segundo par.

5.8.4 Operador seleccionar

último comando seleccionar le permite organizar la interacción interactiva con el usuario. Tiene el siguiente formato:

seleccione nombre [en palabra; ] hacer lista; hecho

Primero de la plantilla palabra Se genera una lista de palabras que coinciden con el patrón. Este conjunto de palabras se muestra en flujo estándar errores, y cada palabra va acompañada número de serie. si el patrón palabra Si se omiten, los parámetros posicionales se derivan de la misma manera. Después de esto, se emite el mensaje estándar de PS3 y el shell espera a que se ingrese la línea en entrada estándar. Si la cadena ingresada contiene un número correspondiente a una de las palabras mostradas, entonces la variable nombre se le asigna un valor igual a esa palabra. Si se ingresa una línea vacía, los números y las palabras correspondientes se muestran nuevamente. Si se ingresa cualquier otro valor, la variable nombre se le asigna un valor de cero. La cadena ingresada por el usuario se almacena en una variable. RESPONDER. Lista de comandos lista ejecutado con el valor de la variable seleccionada nombre.

Aquí hay un pequeño guión:

#!/bin/sh

echo "¿Qué sistema operativo prefieres?"

seleccione var en "Linux" "Gnu Hurd" "BSD gratuito" "Otro"; hacer

romper

hecho

echo "Elegirías $var"

¿Qué sistema operativo prefieres?
1)Linux
2) Gnu Hurd
3) BSD gratis
4)Otro
#?

Pulsa cualquiera de los 4 números sugeridos (1,2,3,4). Si ingresa 1, por ejemplo, verá el mensaje:

"¿Elegirías Linux?"

5.8.5 Operador para

último comando para funciona un poco diferente que en los lenguajes de programación normales. En lugar de aumentar o disminuir el valor de alguna variable en uno cada vez que pasa por el bucle, asigna el siguiente valor de una lista determinada de palabras a la variable cada vez que pasa por el bucle. En general, el diseño se parece a esto:

para el nombre en palabras, haga la lista hecha.

Reglas para construir listas de comandos ( lista) son los mismos que en el operador si.

Ejemplo. El siguiente script crea los archivos foo_1, foo_2 y foo_3:

para a en 1 2 3 ; hacer

toque foo_$a

hecho

EN caso general para declaración tiene el formato:

para nombre [en palabra; ] hacer lista; hecho

Primero, la palabra es revelada. palabra de acuerdo con las reglas de expresión de divulgación dadas anteriormente. Entonces la variable nombre los valores resultantes se asignan uno por uno y cada vez se ejecuta una lista de comandos es. Si " en palabra"Falta, entonces la lista de comandos. lista se ejecuta una vez para cada parámetro posicional que se especifica.

Linux tiene un programa secuencia, que toma dos números como argumentos y produce una secuencia de todos los números ubicados entre los dados. Con este comando puedes forzar para V intento funciona exactamente de la misma manera que funciona un operador similar en lenguajes de programación convencionales. Para hacer esto, simplemente escriba el ciclo. para como sigue:

para a en $(seq 1 10); hacer

archivo de gato_$a

hecho

Este comando muestra el contenido de 10 archivos: " archivo_1", ..., "archivo_10".

5.8.6 Operadores mientras Y hasta

último comando mientras funciona como si, ejecutando solo operadores de la lista lista2 El bucle continúa mientras la condición sea verdadera y se cancela si la condición no es verdadera. El diseño se ve así:

mientras que list1 hace list2 listo.

mientras [-d midirectorio]; hacer

ls -l midirectorio >> archivo de registro

echo -- SEPARADOR -- >> archivo de registro

dormir 60

hecho

Un programa de este tipo registrará el contenido del directorio "midirectorio" cada minuto mientras exista el directorio.

último comando hasta similar al operador mientras:

hasta que list1 haga list2 listo.

La diferencia es que el resultado devuelto al ejecutar una lista de declaraciones lista1, tomado con negación: lista2 ejecutado si el último comando de la lista lista1 devuelve un estado de salida distinto de cero.

5.8.7 Funciones

Sintaxis

Caparazón intento permite al usuario crear funciones nativas. Las funciones se comportan y se utilizan exactamente como los comandos de shell normales, lo que significa que podemos crear nuevos comandos nosotros mismos. Las funciones se construyen de la siguiente manera:

nombre de la función() (lista)

y la palabra función no necesariamente nombre define el nombre de la función mediante la cual se puede acceder a ella, y el cuerpo de la función consta de una lista de comandos lista, ubicado entre ( y ). Esta lista de comandos se ejecuta cada vez que el nombre nombre especificado como el nombre del comando a invocar. Tenga en cuenta que las funciones se pueden definir de forma recursiva, por lo que está permitido llamar a la función que definimos dentro de sí misma.

Las funciones se ejecutan en el contexto del shell actual: para interpretar la función nuevo proceso no se ejecuta (a diferencia de la ejecución de scripts de shell).

Argumentos

Cuando se llama a una función para su ejecución, los argumentos de la función se convierten en parámetros posicionales(parámetros posicionales) mientras dure la función. Se les conoce como $n, Dónde norte— el número del argumento al que queremos acceder. La numeración de los argumentos comienza en 1, por lo que $1 - este es el primer argumento. También podemos obtener todos los argumentos a la vez con $* , y el número de argumentos usando $# . Parámetro posicional 0 no cambia.

Si se produce un comando integrado en el cuerpo de la función devolver, la ejecución de la función se interrumpe y el control se transfiere al comando después de la llamada a la función. Cuando se completa la función, los parámetros posicionales y el parámetro especial # Se devuelven los valores que tenían antes de que comenzara la función.

Variables locales (locales)

Si queremos crear parámetro local, se puede utilizar palabra clave local. La sintaxis para especificarlo es exactamente la misma que para los parámetros normales, solo que la definición está precedida por una palabra clave. locales: locales nombre=valor.

A continuación se muestra un ejemplo de cómo especificar una función que implementa el comando mencionado anteriormente. secuencia:

secuencia()

I local=$1;

mientras [ $2 != $I ]; hacer

eco -n "$yo";

Yo=$(($Yo + 1))

hecho;

eco $2

Tenga en cuenta la opción -norte operador eco, cancela la transición a nueva linea. Aunque esto no es esencial para los propósitos que tenemos en mente aquí, puede resultar útil para utilizar la función para otros fines.

Función de cálculo factorial hecho

Otro ejemplo:

hecho()

si [$1 = 0]; entonces

eco 1;

demás

eco $(($1 * $(hecho $(($1 - 1)))))

Esta es la función factorial, un ejemplo de función recursiva. Tenga en cuenta la expansión aritmética y la sustitución de comandos.

V. Kostromin (kos en rus-linux dot net) - 5.8. Shell como lenguaje de programación

Cualquier sistema operativo universal tiene que jugar mucho con el usuario y sus propias tareas. Sólo una pequeña parte de esta actividad puede programarse de una vez por todas en el kernel. La mayor parte de la lógica para gestionar las tareas y el sistema en sí debe estar disponible para el administrador en forma de proyecto; de lo contrario, simplemente no podrá comprender lo que está sucediendo en el sistema y mucho menos cambiarlo. Vale la pena echar un vistazo más de cerca a la herramienta utilizada en UNIX para configurar el algoritmo para muchas partes del sistema: el intérprete de comandos , caparazón . Resulta que el shell funciona bien no sólo en el diálogo con el usuario, sino también en cómo intérprete de guión, y como medios para organizar la interacción entre tareas en el sistema.

Comencemos con el hecho de que el caparazón está completo. lenguaje de programación, y, como muchos intérpretes, de un nivel bastante alto. Si la tarea es única (no hay requisitos de velocidad, compatibilidad y portabilidad) y bastante abstracta (no hay conexión a una estructura de datos compleja específica), lo más probable es que se pueda resolver. habiendo escrito guión de comando - programa de shell.

Por otro lado, no podemos limitarnos a la integridad algorítmica a la hora de resolver problemas en el sistema. Por ejemplo, la máquina de Turing [9] es extremadamente simple y algorítmicamente completa, pero a pocos se les ocurriría organizar un diálogo con el usuario o controlar el propio sistema operativo basándose en su modelo. Aquí conviene recordar que el shell también es un ejecutor de comandos: se comunica fácilmente con UNIX y utilidades. Esto significa que al complementarlo con un mecanismo para la interacción controlada de comandos con el sistema y entre sí, obtendremos un buen integrador (o shell, que, de hecho, es la traducción de la palabra caparazón).

La mejor parte es que un shell programable de este tipo no irá mucho más allá del alcance de Y: si, como legado de la encarnación interactiva del shell, podemos recurrir fácilmente a la solución de la subtarea cualquier Utilidad UNIX, no es necesario duplicarla en el lenguaje y solo quedarán abstracciones algorítmicas y de coordinación.

Guión

Antes de considerar capacidades de shell Desde dos ángulos de vista, resolvamos esta dificultad. Digamos que escribimos un programa en el lenguaje de algún intérprete, por ejemplo /bin/sh, y lo escribimos en un archivo determinado, por ejemplo /home/george/myscript (si /home/george es el directorio actual, puede usar una ruta más corta: myscript). ¿Cómo puedo ejecutar este script ahora? De man sh sabemos que para hacer esto podemos ejecutar intérprete de comandos con el parámetro - nombre de archivo:

$ cat myscript echo "¡Hola, George!" $ /bin/sh myscript ¡Hola, George!

¿Es posible prescindir del nombre del programa que interpreta el guión? En términos generales, no: UNIX tiene muchos intérpretes diferentes con diferentes sintaxis, por ejemplo el procesador de textos. awk, transmisión editor de texto sed, universal lenguajes de programación Python y Perl y mucho más. Todos estos idiomas tienen la capacidad de insertar comentarios de línea en el texto del script, que comienzan con el carácter "#" y terminan al final de la línea. Por lo tanto, si un guión comienza con los caracteres "#!", cualquiera de estos intérpretes ignorará toda la primera línea como comentario. El sistema, al ver "#!" al principio del archivo, entiende que se trata de un script. Desde el tercer carácter hasta el final de la línea, lee el nombre del programa al que envía este archivo para su ejecución. Esto significa que si la primera línea en /home/george/myscript es #!/bin/sh , puedes convertirla en ejecutable de forma segura (establece el bit de uso) y ejecutarla:

$ chmod +x myscript $ cat myscript #!/bin/sh echo "¡Hola, $1!" $ ./myscript George ¡Hola, George!

Estrictamente hablando, después de "#!" puede ser cualquier cosa, por ejemplo el nombre del programa que escribimos con algunos parámetros requeridos; UNIX lo iniciará y se lo pasará como opciones de línea de comando parámetros requeridos (si los hay), luego el nombre del script y todo lo que viene después (en nuestro ejemplo, George). Si después de "#!" habrá un archivo inexistente, el sistema emitirá mensaje de error:

$ cat myscript #!/bad/sh echo "¡Hola, $1!" $ ./myscript ./myscript: no encontrado

Tenga en cuenta que este mensaje supuestamente implica que no se encontró el archivo de script en sí. Si no se conocen los antecedentes del fenómeno, la situación parece sospechosa. El hecho es que al ejecutar cualquier programa, UNIX Siempre le pasa un parámetro (que tiene índice 0): el nombre de este programa. Pero si se ejecuta el script, el controlador recibirá como parámetro nulo no su propio nombre, sino el nombre del script. Y cuando el sistema no encuentre este controlador, se mencionará con un nuevo nombre en el mensaje de error.

Nidos de conchas

Y una nota más importante. Al principio solo había uno en UNIX intérprete de comandos, escrito por Stephen Bourne, y simplemente se llamaba “shell” (es decir, shell, y el nombre de la utilidad es sh para abreviar). Era un pequeño programa muy simple, funcionó perfectamente así. integrador de sistemas, pero en todos los demás aspectos fue bastante débil. Y entonces a los creadores de 3BSD se les ocurrió que necesitaban un sistema completamente nuevo. intérprete de comandos, más conveniente cuando se trabaja en la línea de comando, con nuevas capacidades de programación y una nueva sintaxis cercana al lenguaje C, que ya es familiar para cualquier programador de UNIX. El shell resultante se llamó C shell (por la sintaxis del comando; el nombre de la utilidad es csh), era mucho más poderoso que el anterior, incluía trabajar con el historial, completar nombres de archivos, gestión del trabajo; Aparecieron matrices y mucho más.




Arriba