Posso chamar uma função de um script de shell de outro script de shell?


86

Eu tenho 2 scripts de shell.

O segundo script de shell contém as seguintes funções second.sh

func1 
func2

O first.sh chamará o segundo script de shell com alguns parâmetros e chamará func1 e func2 com alguns outros parâmetros específicos dessa função.

Aqui está o exemplo do que estou falando

second.sh

val1=`echo $1`
val2=`echo $2`

function func1 {

fun=`echo $1`
book=`echo $2`

}

function func2 {

fun2=`echo $1`
book2=`echo $2`


}

first.sh

second.sh cricket football

func1 love horror
func2 ball mystery

Como posso conseguir isso?



3
v=$(echo $1)é completamente redundante. Basta escrever fun2=$1. A única diferença é que os $()(ou crases) removerão as novas linhas finais.
— William Pursell

1
Como não há nada de especial em chamar uma função de um script de shell em oposição à linha de comando, esta questão pode ser reduzida a "Como chamar uma função bash?"
— Tom Russell,

Respostas:


145

Refatore seu second.shscript assim:

function func1 {
   fun=$1
   book=$2
   printf "fun=%s,book=%s\n" "${fun}" "${book}"
}

function func2 {
   fun2=$1
   book2=$2
   printf "fun2=%s,book2=%s\n" "${fun2}" "${book2}"
}

Em seguida, chame essas funções do script first.shcomo este:

source ./second.sh
func1 love horror
func2 ball mystery

RESULTADO:

fun=love,book=horror
fun2=ball,book2=mystery

12
Para evitar efeitos colaterais não intencionais, tome cuidado para que o sourcecomando realmente execute o script passado como argumento.
— dvlcube

43

Você não pode chamar diretamente uma função em outro script de shell.

Você pode mover suas definições de função para um arquivo separado e, em seguida, carregá-las em seu script usando o .comando, como este:

. /path/to/functions.sh

Isso interpretará functions.shcomo se o conteúdo estivesse realmente presente em seu arquivo neste momento. Este é um mecanismo comum para implementar bibliotecas compartilhadas de funções de shell.


3
Não é a mesma que a resposta aceita, já que .é um alias para source?
— ajsharma de

9
Bem, eu respondi primeiro, então tecnicamente a resposta aceita é a mesma que esta :). Além disso, embora sourceseja um apelido para .em muitos shells, esse nem sempre é o caso. Por exemplo, o dashpacote no Debian, que fornece /bin/sh, não tem um sourcecomando.
— larsks de

sourcecomando não funcionou no Ubuntu @ajsharma. Referência: comando de origem não encontrado no sh shell
— rajeshmag

tão estranho que este comentário não foi votado como o mais alto? Esta é a sintaxe #! / Bin / sh correta e a outra funcionará apenas no bash.
— xddq

20

O problema

A resposta atualmente aceita funciona apenas em condições importantes. Dado...

/foo/bar/first.sh:

function func1 {  
   echo "Hello $1"
}

e

/foo/bar/second.sh:

#!/bin/bash

source ./first.sh
func1 World

isso funciona apenas se o first.shfor executado no mesmo diretório em que first.shestá localizado. Ie. se o caminho de trabalho atual do shell for /foo, a tentativa de executar o comando

cd /foo
./bar/second.sh

imprime erro:

/foo/bar/second.sh: line 4: func1: command not found

Isso porque source ./first.shé relativo ao caminho de trabalho atual, não ao caminho do script. Portanto, uma solução pode ser utilizar subshell e executar

(cd /foo/bar; ./second.sh)

Solução mais genérica

Dado...

/foo/bar/first.sh:

function func1 {  
   echo "Hello $1"
}

e

/foo/bar/second.sh:

#!/bin/bash

source $(dirname "$0")/first.sh

func1 World

então

cd /foo
./bar/second.sh

estampas

Hello World

Como funciona

  • $0 retorna o caminho relativo ou absoluto para o script executado
  • dirname retorna o caminho relativo para o diretório, onde existe o script $ 0
  • $( dirname "$0" )o dirname "$0"comando retorna o caminho relativo para o diretório do script executado, que é então usado como argumento para o sourcecomando
  • em "second.sh", /first.shapenas acrescenta o nome do script de shell importado
  • source carrega o conteúdo do arquivo especificado no shell atual

0

Se você definir

    #!/bin/bash
        fun1(){
          echo "Fun1 from file1 $1"
        }
fun1 Hello
. file2 
fun1 Hello
exit 0

em arquivo1 (chmod 750 arquivo1) e arquivo2

   fun1(){
      echo "Fun1 from file2 $1"
    }
    fun2(){
      echo "Fun1 from file1 $1"
    }

e execute ./file2 você obterá Fun1 de file1 Hello Fun1 de file2 Hello Surprise !!! Você sobrescreve fun1 no arquivo1 com fun1 do arquivo2 ... Para não fazer isso, você deve

declare -f pr_fun1=$fun1
. file2
unset -f fun1
fun1=$pr_fun1
unset -f pr_fun1
fun1 Hello

é salvar sua definição anterior para se divertir1 e restaurá-la com o nome anterior, excluindo não é necessário importar um. Cada vez que você importa funções de outro arquivo, você pode se lembrar de dois aspectos:

  1. você pode sobrescrever os existentes com os mesmos nomes (se for essa a coisa que você deseja, você deve preservá-los conforme descrito acima)
  2. importe todo o conteúdo do arquivo de importação (funções e variáveis ​​globais também). Cuidado! É procedimento perigoso

-5
#vi function.sh

#!/bin/bash
f1() {
    echo "Hello $name"
}

f2() {
    echo "Enter your name: "
    read name
    f1
}
f2

#sh function.sh

Aqui, a função f2irá chamar a funçãof1

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.