2015-04-09 15 views
6

Próbuję naprawić skrypt, który używa echo, czyli za pomocą wbudowanego polecenia zamiast polecenia, w jaki sposób mogę temu zapobiec?Jak uniemożliwić bashowi korzystanie z wbudowanego polecenia?

Wiem, że mogę zrobić /bin/echo, aby wymusić użycie tego, ale nie chciałbym, aby kodować ścieżkę (dla przenośności).

Myślałem, używając coś jak:

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

ale which echo zwrotów: "echo: wierzch wbudowanego polecenia".


ja skończyło się definiując echo funkcję, która używa env jak zaleca @Kenster. W ten sposób nie muszę modyfikować wywołań do echa w skrypcie.

echo() { 
    env echo $* 
} 

# the function is called before the built-in command. 
echo -en "text\nhere" 
+1

"wbudowane polecenie zamiast polecenia" WTF? – ForceBru

+0

Dlaczego nie nazywacie jsut inaczej? –

+0

@El_Hoy: Ciekawe, jak w twoim scenariuszu wewnętrzne echo jest gorsze od '/ bin/echo'? –

Odpowiedz

5

Użyj programu env. Env to polecenie uruchamiające inny program z potencjalnie zmodyfikowanym środowiskiem. Ponieważ env jest programem, nie ma dostępu do wbudowanych powłok, aliasów i innych elementów.

Polecenie to należy uruchomić program echo, szukając go w ścieżce polecenia:

$ env echo foo 

Można to sprawdzić za pomocą strace do monitorowania wywołań systemowych podczas pracy 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)       = ? 
+0

Skończyło się na używaniu twojego rozwiązania, ale przy użyciu funkcji upraszczającej implementację: 'echo() {env echo $ *}' działało świetnie! – eloyesp

6

Możesz wyłączyć wbudowane echo:

enable -n echo 

Teraz po prostu wykonanie echo anything uruchomi wersję zewnętrzną. Wpływa tylko na bieżący proces skryptu, więc możesz bezpiecznie robić to w swoich skryptach.

+0

Fajnie, nie wiedziałem o tym. Czy 'enable' jest wbudowanym poleceniem? Czy działa w 'sh'? – eloyesp

+2

'enable' jest wbudowane w bash (chyba, że' enable -n enable', oczywiście!). To nie działa w POSIX 'sh', ponieważ POSIX nie ma prawdziwego pojęcia wbudowanego vs zewnętrznego. –

+0

Pierwszą rzeczą, która przyszła mi do głowy, gdy "wbudowałem" i "enable" razem, było 'enable -n enable': D. – Samveen

Powiązane problemy