Shell Script para WEB
Poucas pessoas sabem, que é possível usar Shell Script em servidores WEB através de CGI. Esse texto é uma pequena introdução, com alguns exemplos didáticos. Neste tutorial, eu usarei o servidor Apache, com todas as suas configurações padrões.
Parte 2: POST e GET / Exemplos finais
Pegando dados enviados via POST e GET
Quando trabalhamos com desenvolvimento WEB, é comum receber dados via POST e/ou GET. Começarei com o GET, para POST, é praticamente a mesma coisa, só muda mesmo quando se faz upload de arquivos.Em bash script, a variável IFS funciona como uma função split. Colocamos o que será delimitado, a variável seguinte se transforma em um vetor. Depois, usando o laço for, podemos extrair os campos e valores respectivos enviados via GET:
d#!/bin/bash
echo -e "\n"
IFS='=&'
GET=($QUERY_STRING)
for ((i=0; i<${#GET[@]}; i+=2))
do
echo "${GET[@]:$i:1} = ${GET[@]:$i+1:1}"
done
IFS='=&'
GET=($QUERY_STRING)
for ((i=0; i<${#GET[@]}; i+=2))
do
echo "${GET[@]:$i:1} = ${GET[@]:$i+1:1}"
done
Testando:
curl 'localhost/cgi-bin/tutorial.sh?teste=ffff&teste2=xxxxx'
teste = ffff
teste2 = xxxxx
Com POST, a única diferença é que não existe uma variável de ambiente com os valores. Para obter esses valores, basta o seguinte comando: read variavel
Os dados enviados via POST ficam em /dev/stdin, por isso, quando utilizamos o read, esses valores são obtidos. Feito isso, é só trocar o GET por POST:
#!/bin/bash
echo -e "\n"
read var
IFS='=&'
POST=($var)
for ((i=0; i<${#POST[@]}; i+=2))
do
echo "${POST[@]:$i:1} = ${POST[@]:$i+1:1}"
done
echo -e "\n"
read var
IFS='=&'
POST=($var)
for ((i=0; i<${#POST[@]}; i+=2))
do
echo "${POST[@]:$i:1} = ${POST[@]:$i+1:1}"
done
Testando:
curl localhost/cgi-bin/tutorial.sh --data "autor=mmxm&blog=hc0der.blogspot.com"
autor = mmxm
blog = hc0der.blogspot.com
Exemplos finais
Alguns exemplos que podem ser úteis (hehe).Redirecionamento, usando header:
#!/bin/bash
printf "Status: 302 Found\n"
printf "Location: http://hc0der.blogspot.com\n\n";
printf "Status: 302 Found\n"
printf "Location: http://hc0der.blogspot.com\n\n";
Testando:
curl localhost/cgi-bin/tutorial.sh -i
HTTP/1.1 302 Found
Date: Wed, 26 Mar 2014 00:01:08 GMT
Server: Apache/2.2.22 (Debian)
Location: http://hc0der.blogspot.com
Content-Length: 0
Content-Type: text/x-sh
Falso "404 not found":
#!/bin/bash
printf "Status: 404 Not Found\n\n"
printf "Status: 404 Not Found\n\n"
Testando:
curl localhost/cgi-bin/tutorial.sh -i
HTTP/1.1 404 Not Found
Date: Wed, 26 Mar 2014 00:06:53 GMT
Server: Apache/2.2.22 (Debian)
Content-Length: 0
Content-Type: text/x-sh
Fazendo download de arquivos:
#!/bin/bash
arquivo_local=/etc/issue stat -c "Content-Length: %s" $arquivo_local # enviar tamanho do arquivo em bytes
printf "Content-Disposition: attachment; filename=$(basename $arquivo_local)\n"
printf "Content-Type: application/octet-stream\n\n"
cat $arquivo_local
arquivo_local=/etc/issue stat -c "Content-Length: %s" $arquivo_local # enviar tamanho do arquivo em bytes
printf "Content-Disposition: attachment; filename=$(basename $arquivo_local)\n"
printf "Content-Type: application/octet-stream\n\n"
cat $arquivo_local
Testando:
$ curl localhost/cgi-bin/tutorial.sh -i
HTTP/1.1 200 OK
Date: Wed, 26 Mar 2014 00:13:32 GMT
Server: Apache/2.2.22 (Debian)
Content-Disposition: attachment; filename=issue
Content-Length: 17
Vary: Accept-Encoding
Content-Type: application/octet-stream
nao te interessa
E, via browser:

Conclusão
Para uma introdução, está de bom tamanho. Bash Script é complicado, conhecendo bem as ferramentas do seu sistema, não há limites para o que você pode fazer =>.Referências de pesquisas, aqui:
- HTTP/1.1: Response
- List of HTTP header fields Wikipedia, the free encyclopedia
- Linux Tutorial: CGI Shell scripts
- bash How to catch value of parameter in Apache2 CGI Stack Overflow
- How to parse $QUERY_STRING from a bash CGI script Stack Overflow
Artigo também publicado, em: MMxM 8l06: Shell-script para web
That's all folks!
Só não entendi porque você, no exemplo de POST, passou as variáveis com o parâmetro "--data" e não do modo como seria feito em um browser, seguindo o padrão do exemplo do GET: ?var=valor1&var2=valor2
Alguma restrição nesse sentido, para o POST ou poderia ser passado das duas formas ?