Como fazer o shell executar apenas o eco externo, não o interno?

1

Eu tenho um programa em C que usa a função de biblioteca system() . Abaixo está o código fonte.

#include<stdlib.h>
int main()
{ 
    //Some code
    system("echo Hello World");
    //some code
    return 0;
}    

Antes de executar este programa em C, alterei $PATH para que /home/user1/bin/echo fosse executado em vez de /bin/echo

export PATH="/home/user1/bin"

No entanto, quando executei o programa C, ele não executou /home/user1/bin/echo .

É porque echo é shell built-in , por isso, o shell não tentou encontrar echo em $PATH ?

Em caso afirmativo, há alguma alteração que eu possa fazer no shell antes de executar este programa, para que echo seja pesquisado em $PATH em vez de usar o echo incorporado.

    
por sps 24.10.2015 / 23:44

3 respostas

4

command ignora funções, mas não construções de shell. A maneira mais segura seria usar o caminho completo:

system("/home/user1/bin/echo Hello world!")

Se você não puder fazer isso, tente o exec builtin:

system("exec echo Hello World!")

Por exemplo:

$ cat foo.c       
#include<stdlib.h>
int main()
{ 
    //Some code
    system("exec echo --help");
    system("command echo --help");
    system("echo --help");
    //some code
    return 0;
}  
$ gcc -o foo foo.c
$ ./foo
Usage: echo [SHORT-OPTION]... [STRING]...
  or:  echo LONG-OPTION
Echo the STRING(s) to standard output.

  -n             do not output the trailing newline
  -e             enable interpretation of backslash escapes
  -E             disable interpretation of backslash escapes (default)
      --help     display this help and exit
      --version  output version information and exit

If -e is in effect, the following sequences are recognised:

  \      backslash
  \a      alert (BEL)
  \b      backspace
  \c      produce no further output
  \e      escape
  \f      form feed
  \n      new line
  \r      carriage return
  \t      horizontal tab
  \v      vertical tab
  
The environment of the executed command shall be as if a child  process
were created using fork(), and the child process invoked the sh utility
using execl() as follows:

      execl(<shell path>, "sh", "-c", command, (char *)0);
where <shell path> is an unspecified pathname for the sh utility.
NNN byte with octal value NNN (1 to 3 digits) \xHH byte with hexadecimal value HH (1 to 2 digits) NOTE: your shell may have its own version of echo, which usually supersedes the version described here. Please refer to your shell's documentation for details about the options it supports. Report echo bugs to [email protected] GNU coreutils home page: <http://www.gnu.org/software/coreutils/> General help using GNU software: <http://www.gnu.org/gethelp/> For complete documentation, run: info coreutils 'echo invocation' --help --help

A segunda e terceira system chamadas executaram o echo incorporado, que não suporta o --help sinalizador. O primeiro rodou o /bin/echo , no meu caso fornecido pelo GNU, que suportava o --help flag.

De man 3 system (POSIX):

system()  executes a command specified in command by calling /bin/sh -c
command, and returns after the  command  has  been  completed.   During
execution  of  the  command,  SIGCHLD  will  be blocked, and SIGINT and
SIGQUIT will be ignored.

E se você estiver em Linux :

system("/home/user1/bin/echo Hello world!")

Como /bin/sh -c é usado explicitamente, você não pode influenciá-lo por nenhum meio normal - você pode substituir /bin/sh . Isso seria usando um piledriver para pop bubblewrap.

    
por 24.10.2015 / 23:59
3

se você estiver usando bash você pode habilitar e desabilitar comandos internos usando enable

enable -n echo

desativa o comando embutido echo.

    
por 24.10.2015 / 23:56
1

Existe o comando command para isso.

Aparentemente, você não pode.

BTW, tenha muito cuidado com system() se você se preocupa com questões de segurança.

    
por 24.10.2015 / 23:50

Tags