Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prevent bash to use a builtin command?

Tags:

bash

sh

built-in

I'm trying to fix a script that use echo, that is using the builtin command instead of the command, how can I prevent that?

I know I can do /bin/echo to force the usage of that, but I wouldn't like to hardcode the path (for portability).

I thought using something as:

$ECHO=`which echo`
$ECHO -e "text\nhere"

but which echo returns: "echo: shell built-in command".


I've ended up defining an echo function that uses env as @Kenster recommends. This way I don't need to modify the calls to echo in the script.

echo() {
  env echo $*
}

# the function is called before the built-in command.
echo -en "text\nhere"
like image 271
eloyesp Avatar asked Apr 09 '15 13:04

eloyesp


People also ask

Why would a command be built into the shell?

Some commands have to be built into the shell program itself because they cannot work if they are external. cd is one such since if it were external, it could only change its own directory; it couldn't affect the current working directory of the shell. (See also: Why is cd not a program?)

How do you stop a command in Bash?

There are many methods to quit the bash script, i.e., quit while writing a bash script, while execution, or at run time. One of the many known methods to exit a bash script while writing is the simple shortcut key, i.e., “Ctrl+X”. While at run time, you can exit the code using “Ctrl+Z”.

How do I stop a bash script execution?

If you are executing a Bash script in your terminal and need to stop it before it exits on its own, you can use the Ctrl + C combination on your keyboard.

How do I stop a shell script from command?

To end a shell script and set its exit status, use the exit command. Give exit the exit status that your script should have. If it has no explicit status, it will exit with the status of the last command run.


1 Answers

Use the env program. Env is a command which launches another program with a possibly modified environment. Because env is a program, it doesn't have access to shell builtins, aliases, and whatnot.

This command will run the echo program, searching for it in your command path:

$ env echo foo

You can verify this by using strace to monitor system calls while running echo vs env echo:

$ strace -f -e trace=process bash -c 'echo foo'
execve("/bin/bash", ["bash", "-c", "echo foo"], [/* 16 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f153fa14700) = 0
foo
exit_group(0)                           = ?

$ strace -f -e trace=process bash -c 'env echo foo'
execve("/bin/bash", ["bash", "-c", "env echo foo"], [/* 16 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f474eb2e700) = 0
execve("/usr/bin/env", ["env", "echo", "foo"], [/* 16 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f60cad15700) = 0
execve("/usr/local/sbin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/local/bin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/sbin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/bin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/sbin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/bin/echo", ["echo", "foo"], [/* 16 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f0146906700) = 0
foo
exit_group(0)                           = ?
like image 171
Kenster Avatar answered Oct 06 '22 19:10

Kenster