我可以定义一个函数如下:
myfunction () { ls -R "$1" ; }
进而
myfunction .
就可以了。
但如果我这么做
echo "myfunction ." | sh
echo "myfunction ." | bash
这些信息是:
sh: myfunction: not found
bash: line 1: myfunction: command not found
为什么?如果不通过管道传输到 sh 或 bash,如何调用来自字符串的函数?
我知道有这个命令source
,但我不知道什么时候应该使用source
,什么时候sh
应该使用bash
。另外,我无法通过管道传输source
。更令人困惑的是,这个命令.
似乎与表示“当前目录”的“.”无关。
答案1
除了使用eval
,您还可以使用export
自己的函数,以便由子 shell 继承它:
myfunction () { ls -R "$1" ; }
export -f myfunction
进而
echo "myfunction ." | bash
就可以了。
echo "myfunction ." | sh
可能不会,除非你的 /bin/sh 是 bash 的符号链接。
答案2
函数定义只在当前 bash 实例中有效。当你写
echo "myfunction ." | bash
您运行另一个 bash 实例。您需要在该实例中定义该函数。
如果您有一个包含函数名称和参数(如果需要,可以用引号引起来)的字符串,或者更一般地说,任何包含要执行的某些 shell 源代码的字符串,请使用内置函数eval
。
my_snippet='myfunction .'
eval "$my_snippet"
如果您在 中定义函数.bashrc
,它们仅在交互式 shell 中可用,而不是在脚本中可用。
该.
命令(几乎)等同于,与当前目录的含义source
无关。.
答案3
bash
并sh
期望它们的参数是一个可执行文件,而不是一个字符串。
你可以使用以下命令执行字符串的内容
eval "myfunction ."
当您通过 shell 运行程序时,它通常会调用 的新实例bash
(或sh
、csh
、zsh
等,视情况而定),继承所有原始 shell 的设置,并在新 shell 中运行自身。这样您就可以临时设置变量或更改设置,而不会干扰您的环境。
source
执行命令将使其在你当前的 shell 中运行,因此它对环境所做的任何更改都将在命令退出时保留下来。.
是 的同义词source
。
在大多数情况下,脚本会指定它要在哪个 shell 中运行(#!/bin/bash
例如,在其第一行),并且您不需要明确调用 bash。