Como executar um bloco de shell script em C [RESOLVIDO]

1. Como executar um bloco de shell script em C [RESOLVIDO]

Ghoost User
ghoostuser

(usa Arch Linux)

Enviado em 06/07/2015 - 01:36h

Galera, seguinte...gostaria de saber como que executo um bloco de shell script dentro do meu código C.
Sei que se usa a função "system()" pra isso, mas necessito utilizar um "if...else" de shell script em C. Por exemplo:


static const char * _verify=
"packageNpm=$(dpkg --get-selections | grep npm )"
"if [[ -n \"packageNpm\" ]]; then\n"
npm install -g grunt grunt-cli
")else (\n"
"echo \"Npm não instalado\" \n"
")fi";


Tenho essa função e quero executar esse bloco. Já tentei colocar dentro da função "system()" do C, mas não consegui.

Alguem pode me ajudar?

Grato por ler. :)


  


2. Re: Como executar um bloco de shell script em C

Perfil removido
removido

(usa Nenhuma)

Enviado em 06/07/2015 - 02:04h

Tem muitas aspas. Você deveria usar barra ao contrário \.
Era prá ser uma string única. Não um vetor de strings.

--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden


3. Re: Como executar um bloco de shell script em C

Perfil removido
removido

(usa Nenhuma)

Enviado em 06/07/2015 - 03:23h

Fiz meu código e testei:

#include <stdio.h>

const char comm[] = "for i in `seq 1 10`; \
do \
echo $i; \
done;";

main() {

system(comm);

}


O código acima imprime de 1 a 10, com um número por linha corretamente.

#include <stdio.h>

const char comm[] = "for i in {1..10}; \
do \
echo $i; \
done;";

main() {

system(comm);

}


Já o código acima simplesmente imprime {1..10} errado.

Só não vá me colocar rm -rf / dentro do system.

--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden


4. Re: Como executar um bloco de shell script em C [RESOLVIDO]

Ghoost User
ghoostuser

(usa Arch Linux)

Enviado em 06/07/2015 - 07:14h

listeiro_037 escreveu:

Fiz meu código e testei:

#include <stdio.h>

const char comm[] = "for i in `seq 1 10`; \
do \
echo $i; \
done;";

main() {

system(comm);

}


O código acima imprime de 1 a 10, com um número por linha corretamente.

#include <stdio.h>

const char comm[] = "for i in {1..10}; \
do \
echo $i; \
done;";

main() {

system(comm);

}


Já o código acima simplesmente imprime {1..10} errado.

Só não vá me colocar rm -rf / dentro do system.

--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden




Hahaha pode deixar, vou colocar isso no "system" não hehe.

Então, eu não consegui...mudei o código, tirei as aspas, compilou, rodou sem erros, mas não apareceu nada : (
Veja ai:


#include <stdio.h>

const char verify[] = "#!/bin/bash \
packageNpm=$(dpkg --get-selections | grep npm ) \
if [[ -n $packageNpm ]]; then( \
echo Npm existe. Instalando ... \
npm install -g grunt grunt-cli
)else( \
echo Npm não instalado \
)fi";

main() {
system(verify);
}



5. Re: Como executar um bloco de shell script em C [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 06/07/2015 - 07:43h

Parece-me que precisa colocar ponto-e-vírgula após cada comando de shell.
E o if ... then ... else ... fi de shell não usa parêntesis ou chaves.

 char comm[] = "if [teste]; \
then \
...; \
...; \
else \
...; \
...; \
fi;";


É mais ou menos isto.

--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden


6. Re: Como executar um bloco de shell script em C [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 06/07/2015 - 08:01h

Simplifiquei e agora funciona alguma coisa:

#include <stdio.h>

const char verify[] = "packageNpm=$(dpkg --get-selections | grep npm); \
if [ -n \"$packageNpm\" ]; then \
echo Npm existe. Instalando ...; \
npm install -g grunt grunt-cli; \
else \
echo Npm não instalado; \
fi";

main() {
system(verify);
}

--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden


7. Re: Como executar um bloco de shell script em C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 07/07/2015 - 17:00h

Algumas observações quanto à solução dada pelo listeiro_037.

1) Eu não gosto da solução de colocar uma barra invertida (“\”) no final de cada linha, dentro de um só string, como método de embutir uma quebra de linha na string. Se alguém, por acidente, colocar um espaço depois da barra e antes da quebra de linha, esse espaço pode ficar invisível no editor de textos, mas vai impedir o programa de compilar direito. Outro problema relacionado é se o arquivo for, por exemplo, gerado no Windows e levado para compilar no Linux, pois a quebra de linha em arquivos de texto do Windows é composta por dois caracteres (CR+LF) e, no Linux, apenas por um (LF). A sequência “\”+CR+LF é uma linha de continuação no Windows, mas não no Linux, pois ele esperaria encontrar apenas “\”+LF.

Então, em vez de fazer algo como

char string_unica[]="Primeira linha.\
Segunda linha.\
Terceira linha.";


eu prefiro -- e sugiro -- fazer de um dos seguintes modos.

char string_unica[]="Primeira linha.\nSegunda linha.\nTerceira linha."; 


char string_unica[]=
"Primeira linha.\n"
"Segunda linha.\n"
"Terceira linha."
;


2) A quebra de linhas entre comandos do shell é meramente estética. A rigor, ela poderia ser suprimida, e comandos consecutivos, incluindo laços de repetição e blocos de if/elif/.../else/fi, poderiam ser escritos em linha, simplesmente separados com sinais de ponto-e-vírgula, nos lugares adequados.

3) Eu acho melhor ser bem específico com relação ao shell que será usado pela função system(). A função system executa como interpretador de comandos o /bin/sh. No ramo de Red Hat (Fedora, CentOS e outros), /bin/sh é um link para /bin/bash; no Debian e derivados (Ubuntu, Mint etc.), /bin/sh é distinto do /bin/bash, possivelmente usando o /bin/dash (que é menor e mais rápido, mas tem menos recursos). Em outros sistemas, pode ser que o /bin/sh use ainda outra coisa, como o ksh, pdksh ou algo ainda mais criativo.

O script mostrado na listagem tem pelo menos um recurso que não é universalmente disponível: a substituição com “$(comando)” não funciona no /bin/sh original, que ainda é encontrável no Solaris e talvez ainda aflija alguns Linuxes mais antigos.

Então, das duas, uma: ou se adapta o script para não usar esse recurso, ou se força o uso de um interpretador específico para aquela linha de comando.

/* Força chamar o bash para interpetar os comandos. */
system("exec /bin/bash -c 'comandos ...'");


(Desnecessário dizer que aqueles apóstrofos em torno dos comandos geram seus próprios cuidados, certo?)

4) Lembrem-se que os padrões do C de 1999 e de 2011 tornaram obsoleta a definição de main() sem se declarar o tipo de retorno. Além disso, é necessário dizer que essa função ou não recebe parâmetro nenhum (“int main(void)”) ou recebe um contador de argumentos e uma lista de strings passadas como argumentos individuais para o programa (“int main(int argc, char **argv)”).


8. Re: Como executar um bloco de shell script em C [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 07/07/2015 - 20:11h

A quebra de linha neste caso não influi muito porque é prá ser executado em algum tipo de Unix.
A notação $() foi usada por causa de exec ser um comando embutido e não um executável;
Eu desconfiei de se usar /bin/sh como padrão, mas não tinha conseguido rodar /bin/bash.
Será que é viável colocar algo como /bin/bash -c \"...............................\" dentro do system?

--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden


9. Re: Como executar um bloco de shell script em C

Ghoost User
ghoostuser

(usa Arch Linux)

Enviado em 08/07/2015 - 15:31h

Interessante Paulo, gostei muito das explicações, aprendi mais um pouquinho. Usar o "\n", usei e deu certo com esse script, porem estendi mais ele e obtive umas complicações...ai fico pensando, acho melhor eu criar um arquivo "shell" pelo C no diretório temp, executa-lo e depois remove-lo, do que ficar colocando toda essa complicação ai de "\n", o que me diz?. Acho tambem que não é viavel igual nosso colega disse, colocar os comandos diretamente no "system()", pelo menos pra mim, que vou usar um bloco de script shell grandinho. Como eu disse eu estendi o script utilizando, coloquei um case... in, compilou, não deu erro, mais não traz o resultado, veja ai:


#include <stdio.h>
#include <locale.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <dirent.h>

const char scriptshell[] =
"#!/bin/bash\n"
"function _initial(){\n"
"packageNpm=$(dpkg --get-selections | grep npm)\n"
"if [[ -n $packageNpm ]]; then\n"
"echo Npm existe. Instalando ...;\n"
"else\n"
"echo Npm não instalado;\n"
"fi;\n"
"}\n"
"case \"$1\" in\n"
"start)\n"
"_initial\n"
";;\n"
"help)\n"
"echo 'help test';\n"
";;\n"
"*)\n"
"echo 'Usage: { start | help }';\n"
";;\n"
"esac\n"
"exit 0";

void main() {
system(scriptshell);
}



Na verdade, esse case, menuzinho, fiz só pra estender mesmo esse "char", pra ver se dava erro o system() rodar algo extenso e só pra explicar de como estou tendo dificuldade em rodar um bloco de shell script pelo system(). Eu fiz um menu pelo C já.

Obrigado :)


10. Re: Como executar um bloco de shell script em C [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 08/07/2015 - 18:50h

O que aconteceu?
--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden


11. Re: Como executar um bloco de shell script em C [RESOLVIDO]

Ghoost User
ghoostuser

(usa Arch Linux)

Enviado em 08/07/2015 - 23:45h

listeiro_037 escreveu:

O que aconteceu?
--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden



Não esta retornando resultado. Compilou certo, rodei ele...apareceu o menu, mas quando eu coloco uma opçao, por exemplo:
"sudo ./script start" ele não retorna, ele mostra o menu, ou seja, sempre esta entrando no trecho:

*)
echo 'echo help'
;;


:(


12. Re: Como executar um bloco de shell script em C [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 08/07/2015 - 23:57h

Você pode implementar o menu em C e deixar para o system() rodar só o comando das opções.
Quanto ao defeito, estou analisando.
--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts