Chamadas a scripts. Exportar variables

De Manuais Informática - IES San Clemente.
Revisión del 19:41 6 oct 2017 de Carrion (discusión | contribuciones) (Experimentaación con source ou ".")
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Ir a la navegación Ir a la búsqueda

Introdución

  • Antes de comezar cos scripts que creen o esqueleto das carpetas do noso dominio, imos explicar brevemente como funciona a execución de scripts en Linux e a chamada entre eles:
    • Calquera proceso en Linux ten asignado un número de proceso.
    • Cada proceso en Linux non comparte nada con outros procesos e ten as súas propias variables.
    • As variables poden pasarse de procesos pai a procesos fillos con export
    • Cando se chama a un script, dependendo como se chame pódese crear un novo proceso fillo ou non.
    • A consola é un proceso, que ten as súas variables e o seu número de proceso correspondente.
    • sh script.sh: sh é un intérprete de comandos que abre un novo proceso fillo para executar o script.
    • source script.sh: source indica que se colla o contido do ficheiro script.sh e o execute como se as liñas se teclearan dende o proceso que chama ao script. Non se crea un proceso fillo, seguimos no mesmo proceso pai, só que o contido de script.sh foi traído ao proceso no que estamos.
    • . script.sh: é o mesmo que source script.sh
    • PATH: variable de contorna que indica os directorios nos que buscar executables.
    • Cando se inicia unha terminal ábrese un proceso que ten un id. este pódese consultar con echo $$


  • Imos agora con varios exemplos de todo o anterior:

Abrimos un terminal e imos crear en /root/scripts que vai conter os scripts

#Comezamos creando un directorio en dserver00 no que ter organizados tódolos scripts.
mkdir scripts
cd scripts

Os procesos e o contorno de traballo onde se executa un script

SCRIPT: pai.sh

1 #!/bin/bash
2 
3 echo Son o script pai
4 echo Teño o proceso número: $$
5 
6 CIDADE=Santiago
7 
8 echo Como pai defino a variable Cidade, con valor $CIDADE


  • Probas iniciais:
#Comprobamos que numero de proceso ten o terminal no que imos lanzar os scripts.
root@dserver00:~/scripts# echo $$
  3000

#Comprobamos en que ruta estamos.
root@dserver00:~/scripts# pwd 
  /root/scripts

#Comprobamos que o ficheiro pai.sh existe e non ten permisos de execución
root@dserver00:~/scripts# ls pai.sh -l
  -rw-r--r-- 1 root root 233 Mai 10 13:39 pai.sh


Chamar a un script co inteprete sh

root@dserver00:~/scripts# sh pai.sh
  Son o script pai
  Teño o proceso número: 3830
  Como pai defino a variable Cidade, con valor Santiago

#Observar como o número do proceso do terminal é 3000 e o nº de proceso mentres se executaba o script era 3830
#Falamos en pasado porque ese proceso xa non existe unha vez que rematou o script. 

#Miramos no terminal que valor ten a variable CIDADE que está dentro do script e que se acaba de executar
root@dserver00:~/scripts# echo $CIDADE
root@dserver00:~/scripts#

#Non ten valor no proceso da terminal. Non existe esa variable no terminal,
#pois unha vez que finalizou o script matouse o seu proceso asociado e 
#as variables que nese proceso se definiran.

Executar un script con source ou con "."

  • Cando se chama a un script con source ou "." é como se as liñas dese script se copiaran ao proceso actual, isto é, neste caso, na terminal:
#Antes de nada volvemos mirar no terminal que valor ten a variable CIDADE que está dentro do script
root@dserver00:~/scripts# echo $CIDADE
  root@dserver00:~/scripts#
#Polo explicado antes, non existe esa variable. 

#Revisamos de novo o número de proceso do terminal, que era 3000
root@dserver00:~/scripts# echo $$
  3000

root@dserver00:~/scripts# . pai.sh 
  Son o script pai
  Teño o proceso número: 3000
  Como pai defino a variable Cidade, con valor Santiago

# Observar agora que non se creou un novo proceso para executar o script, pois dentro do proceso 3000
# o que se fixo foi traer o contido do ficheiro e executar liña a liña dese ficheiro dentro do 
# proceso 3000 (O terminal)

# Por tanto, que pasa agora coa variable cidade no terminal? no proceso 3000?
root@dserver00:~/scripts# echo $CIDADE 
  Santiago

#Pois que agora a variable CIDADE existe no proceso 3000 (a terminal) e ten valor.

Executar o script chamándoo directamente polo seu nome. A variable de contorno PATH

#Para iso o script ten que ser executable. Por agora non o é.
root@dserver00:~/scripts# ls pai.sh -l
  -rw-r--r-- 1 root root 233 Mai 10 13:39 pai.sh
 
#Dámoslle permiso de execución ao script. 
root@dserver00:~/scripts# chmod +x pai.sh
root@dserver00:~/scripts# ls pai.sh -l
  -rwxr-xr-x 1 root root 233 Mai 10 13:45 pai.sh

 #Chamamos ao script dende dentro do propio directorio que o contén. Pero dinos que non existe.
root@dserver00:~/scripts# pai.sh
  -bash: pai.sh: command not found

# Se miramos a variable PATH, vemos onde se buscan os ficheiros executables
# se non se lles indica unha ruta como no caso anterior
# A variable PATH é unha variable do sistema que herdan tódolos procesos fillos, entre eles a consola actual
root@dserver00:~/scripts# echo $PATH
  /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Antes de indicar como poderíamos modificar esa variable imos ver que pasa se lle poñemos a ruta ao script.
# Ruta absoluta:


# Poderíamos engadir á variable PATH
# Ruta absoluta ao script
root@dserver00:~/scripts# /root/scripts/pai.sh 
  Son o script pai
  Teño o proceso número: 3852
  Como pai defino a variable Cidade, con valor Santiago

# Ruta relativa: dende o directorio actual no que estamos. 
# Lembrar que o directorio no que estamos sempre se denomina . (non confundir co . de source).
root@dserver00:~/scripts# ./pai.sh 
  Son o script pai
  Teño o proceso número: 3853
  Como pai defino a variable Cidade, con valor Santiago 

# En ámbolos dous casos o script execútase pois puxemos unha ruta para chegar até el.
# Observar como se abriron novos procesos para executar o script en cada chamada.
# No proceso 3000 (a terminal) seguimos tendo a variable CIDADE da execución anterior con source ou .
 

#A variable PATH pódese modificar para a sesión actual do terminal (proceso 3000) como segue
PATH=$PATH:./ # Para engadir ao PATH actual o directorio no esteamos en cada momento 
# ou 
PATH=$PATH:/root/scripts # Ruta absoluta a onde se atopa os scripts que desexamos executar.
# Executamos agora o script simplemente chamándoo polo seu nome dende calquera sitio
root@dserver00:~/scripts# pai.sh 
  Son o script pai
  Teño o proceso número: 3856
  Como pai defino a variable Cidade, con valor Santiago 
# Outro novo proceso.

# Tan pronto se peche o terminal actual PATH volverá ao seu valor orixinal, perderanse os cambios realizados,
# pois eses cambios pertencen ao proceso 3000.
# Se desexamos facer permanentes eses valores podemos:
## Modificar a variable PATH en /etc/profile -> Afectaría a todo o sistema (Tódolos usuarios).
## Engadir PATH=$PATH:<directorios que se desexan> no fichiero .bashrc da carpeta persoal do usuario que 
## desexa ter una PATH personalizado e que non afecte ao sistema nin a outros usuarios.

Chamadas entre procesos

Chamadas aos scripts dende o terminal

  • Imos chamar a dous scripts. O segundo usa unha variable que define o primeiro, pero imos chamalos de forma independente dende a consola.
  • Imos saír do terminal e volver entrar, para comezar de novo e que PATH non teñan en conta os cambios anteriores, nin exista a variable CIDADE.
  • Creamos un novo script en /root/scripts e situámonos nese directorio.

SCRIPT: fillo.sh

1 #!/bin/bash
2 
3 echo Son o script fillo
4 echo Teño o proceso número: $$
5 echo Meu pai define a variable Cidade, con valor $CIDADE


Experimentación con sh

# O novo terminal ten o número de proceso 4000
root@dserver00:~/scripts# echo $$
  4000
#Chamamos ao proceso pai e execútase dentro dun novo proceso, 
#que se destrúe ao rematar o script, e por tanto as variables que se usaran. 
root@dserver00:~/scripts# sh pai.sh 
  Son o script pai
  Teño o proceso número: 4023
  Como pai defino a variable Cidade, con valor Santiago
# Chamamos ao proceso fillo e execútase dentro dun novo proceso que se destrúe ao saír. 
# Non pode coller o valor da variable CIDADE porque esa variable era do proceso anterior (4023) e 
# destruíuse cando rematou o script/anterior.
root@dserver00:~/scripts# sh fillo.sh 
  Son o script fillo
  Teño o proceso número: 4024
  Como pai defino a variable Cidade, con valor

Experimentación con source ou "."

root@dserver00:~/scripts# . pai.sh 
  Son o script pai
  Teño o proceso número: 4000
  Como pai defino a variable Cidade, con valor Santiago
# Neste caso o contido de pai.sh executouse liña a liña dentro do proceso 4000 (a terminal).

# Chamamos ao proceso fillo.sh co intérprete sh.
# Pero vemos que se crea un novo proceso (4027) que non sabe cales son as variables
# que hai no proceso 4000. Por iso non sabe o valor da variable CIDADE
root@dserver00:~/scripts# sh fillo.sh 
  Son o script fillo
  Teño o proceso número: 4027
  Meu pai define a variable Cidade, con valor 

# Chamamos ao proceso fillo.sh dende o terminal con source ou .
# Co cal, estamos executando liña a liña dentro do proceso 4000. 
# E como antes fixemos o mesmo con pai.sh, 
# agora a variable CIDADE ten senso dentro do proceso 4000 (terminal)
root@dserver00:~/scripts# . fillo.sh 
  Son o script fillo
  Teño o proceso número: 4000
  Meu pai define a variable Cidade, con valor Santiago.

Chamar a un script dende outro script: Export

  • Para non interferir nesta última experimentación que imos facer, volvemos pechar o terminal e volvemos entrar.
  • Para que a variable teña CIDADE, definida dentro de pai.sh, teña senso dentro de fillo.sh imos facelo de 2 maneiras:

Chamar dende o fillo ao pai

  • Primeiro imos chamar dende fillo.sh ao script pai.sh

Chamar de fillo a pai: usando o intérprete sh

  • Modificamos o contido dos script fillo.sh como segue:

SCRIPT: fillo.sh

1 #!/bin/bash
2 
3 sh pai.sh
4 echo =======================================
5 
6 echo Son o script fillo
7 echo Teño o proceso número: $$
8 echo Meu pai define a variable Cidade, con valor $CIDADE
  • A liña 3 tamén podería ser ./pai.sh se pai.sh tivera permisos de execución. Ou pai.sh se ademais dos permisos estivera o directorio no PATH


  • Experimentación
# Dende o terminal chamamos a fillo.sh 
# Créase un novo proceso para ese script. (4051)
# O script fillo.sh chama a script pai.sh que define a variable CIDADE pero que a destrúe 
# tan pronto como remata a súa execución e devolve o control a fillo.sh que non sabe nada desa variable.
# Observar polos números de proceso que se crea antes o fillo cao pai.
root@dserver00:~/scripts# sh fillo.sh 
  Son o script pai
  Teño o proceso número: 4050
  Como pai defino a variable Cidade, con valor Santiago
  Chamando a fillo.sh
  =======================================
  Son o script fillo
  Teño o proceso número: 4051
  Meu pai define a variable Cidade


Chamar de fillo a pai: usando source ou "."

  • Modificamos o contido dos script fillo.sh como segue:

SCRIPT: fillo.sh

1 #!/bin/bash
2 
3 . ./pai.sh  #é o mesmo que source ./pai.sh
4 echo =======================================
5 
6 echo Son o script fillo
7 echo Teño o proceso número: $$
8 echo Meu pai define a variable Cidade, con valor $CIDADE
  • A liña 3 tamén podería ser . pai.sh, pero cando se chamase ao script, no cando de sh fillo.sh deberamos chamalo como . fillo.sh (ou source fillo.sh). Neste caso o contorno de execución sería o do terminal, executaríase todo co mesmo número de proceso.


  • Experimentación
# Dende o terminal chamamos a fillo.sh 
# Créase un novo proceso para ese script. 
# O script fillo.sh executa as liñas de pai.sh como se as tivera el tecleadas no propio script, pois 
# pai.sh é chamado con source ou "."
# Observar en que número de proceso se executan os dous scripts.
root@dserver00:~/scripts# sh fillo.sh 
  Son o script pai
  Teño o proceso número: 4060
  Como pai defino a variable Cidade, con valor Santiago
  Chamando a fillo.sh
  =======================================
  Son o script fillo
  Teño o proceso número: 4060
  Meu pai define a variable Cidade, con valor Santiago

Chamar dende o pai ao fillo: export

  • Veremos tamén dúas formas
  • No segundo caso exportaremos unha variable do pai ao fillo.

Chamar de pai a fillo: usando o intérprete sh

  • Modificamos o contido dos script fillo.sh como segue (Eliminamos a liña que chamaba ao script pai.sh):

SCRIPT: fillo.sh

1 #!/bin/bash
2 
3 echo =======================================
4 echo Son o script fillo
5 echo Teño o proceso número: $$
6 echo Meu pai define a variable Cidade, con valor $CIDADE


  • Modificamos o contido do script pai.sh como segue:
 1 #!/bin/bash
 2 
 3 echo Son o script pai
 4 echo Teño o proceso número: $$
 5 
 6 CIDADE=Santiago
 7 
 8 echo Como pai defino a variable Cidade, con valor $CIDADE
 9 
10 echo Chamando a fillo.sh
11 sh fillo.sh


  • Experimentación
# Dende o terminal chamamos a pai.sh 
# Créase un novo proceso para ese script. (4070)
# O script pai.sh chama a script fillo.sh e crease un novo proceso (4071), 
# Pero a variable CIDADE é so do contorno do pai, non dos fillos. 
# Observar polos números de proceso cal se crea antes.
root@dserver00:~/scripts# sh pai.sh 
  Son o script pai
  Teño o proceso número: 4070
  Como pai defino a variable Cidade, con valor Santiago
  Chamando a fillo.sh
  =======================================
  Son o script fillo
  Teño o proceso número: 4071
  Meu pai define a variable Cidade


Chamar de pai a fillo: exportando variables

  • Finalmente:
  • Exportar unha variable do pai aos fillos: "export"
  • Modificamos o contido do script pai.sh como segue:
 1 #!/bin/bash
 2 
 3 echo Son o script pai
 4 echo Teño o proceso número: $$
 5 
 6 CIDADE=Santiago
 7 export CIDADE # As 2 liñas poderían quedar nunha soa: export CIDADE=Santiago
 8 
 9 echo Como pai defino a variable Cidade, con valor $CIDADE
10 
11 echo Chamando a fillo.sh
12 sh fillo.sh


  • Experimentación
# Dende o terminal chamamos a pai.sh 
# Créase un novo proceso para ese script. (4080)
# O script pai.sh chama a script fillo.sh e crease un novo proceso (4081), 
# Pero antes de chamalo exportou a variable CIDADE, co cal esta vai estar dispoñible para
# tódolos scripts que se chamen dende o pai, aínda que os fillos se executen noutro proceso distinto.
# Observar polos números de proceso cal se crea antes, e como o proceso fillo ten acceso á variable CIDADE
root@dserver00:~/scripts# sh pai.sh 
  Son o script pai
  Teño o proceso número: 4080
  Como pai defino a variable Cidade, con valor Santiago
  Chamando a fillo.sh
  =======================================
  Son o script fillo
  Teño o proceso número: 4081
  Meu pai define a variable Cidade, con valor Santiago



-- Antonio de Andrés Lema e Carlos Carrión Álvarez