How to prevent the use of bash built-in command?

I am trying to fix a script that use echo that uses a built-in command instead of a command, how can I prevent this?

I know that I can do /bin/echo to force this, but I would not want to hard-code the path (for portability).

I was thinking of using something like:

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

but which echo returns: "the echo: shell command is inline".


I defined an echo function that uses env , as @Kenster recommends. This way, I do not need to modify the echo calls in the script.

 echo() { env echo $* } # the function is called before the built-in command. echo -en "text\nhere" 
+6
source share
2 answers

Use the env program. Env is a command that starts another program with a possibly modified environment. Since env is a program, it does not have access to the shell's built-in shells, aliases, or anything else.

This command starts the echo program, looking for it in your path to the command:

 $ 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) = ? 
+5
source

You can disable the built-in echo:

 enable -n echo 

Now just executing echo anything will launch the external version. This only affects the current script process, so you can safely execute it in your scripts.

+6
source

Source: https://habr.com/ru/post/984896/


All Articles