shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Script de Upload


From: Humberto Pereira
Subject: Re: [shell-script] Script de Upload
Date: Fri, 17 Mar 2006 15:02:05 -0300
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060130 SeaMonkey/1.0

Olah,

um upload eh arquivo eh algo bastante simples. Voce tem um boundary (q limita o comeco e final do arquivo), alguns cabecalhos com informacoes do arquivo e no meio vem o arquivao. Algo do tipo:

-------------------------------12345678
Content-Disposition: form-data; name="myfile"; filename="ad.gif"
Content-Type: image/gif

[conteudo do arquivo binario]
-------------------------------12345678--


Todas essas informacoes vem em stdin.

Regras:

1) Informacoes estao entre um boundary e o limite dele (o limite eh sempre o boundary + '--'); 2) Logo apos o boundary vem os cabecalhos, q sao separados do arquivo por uma linha em branco (conhecida sequencia \r\n\r\n no protocolo HTTP);
3) O resto eh o seu arquivo.

Usar echo p/ trabalhar com arquivos binarios nao eh uma boa ideia. Mas o sed consegue fazer isso bem, entao, seguindo as regrinhas podemos montar
um file uploader.

--- uploader.sh ---
#!/bin/bash

# copia o upload inteiro de stdin p/ um arquivo temporario
tmp_file=`mktemp`

sed -n '1,$p' > $tmp_file

# pegamos o boundary conforme o seu script
boundary=$(export | sed '/CONTENT_TYPE/!d;s/^.*dary=//;s/.$//')

# pegamos o nome do arquivo conforme o seu script *
filename=$(sed -n '2!d;s/\(.*filename=\"\)\(.*\)\".*$/\2/;p' $tmp_file)

# pegamos tudo q esta entre os boundary
sed -n "/^$boundary$/,/^$boundary--$/ { /^$boundary$/d; /^$boundary--$/d; p; }" $tmp_file > "${tmp_file}_nobound"


# removemos os cabecalhos e jogamos finalmente no arquivo
# final
sed '1,/^$/d; $d;' "${tmp_file}_nobound" > /tmp/$filename

--- uploader.sh ---


Ele deveria funcionar perfeitamente, nao fosse um pequeno detalhe.
A ultima linha termina com \r\n e o sed nao remove ela. Nao sei como remover os 2 ultimos bytes de um arquivo em shell, talvez alguem da lista possa dizer.

Outro detalhe eh q ele funciona perfeitamente se vc fizer upload de 1, e apenas 1 arquivo, p/ + arquivos voce vai ter q quebrar a cabeca 1 pouco.


[]s
Humberto Pereira
        
Giuseppe Fontana wrote:
Olá pessoal. Peguei um Script do Thobias Salazar Trevisan na Internet, que faz Upload de arquivos em HTML com CGI. Mas para isso, eu não posso usar o Perl, nem PHP, Python, apenas bash.

O Script foi feito para enviar somente arquivos de texto, então queria adaptar ele para enviar arquivos de conteúdo binário, como fotos, docs, etc.

Pedi ajuda ao Flavio Torres, e ele coitado acabou perdendo dois dias comigo tentando descobrir uma forma de enviar os dados. Inclusive chegamos a conclusão que o Script só envia arquivos de texto.

Abaixo vai os Scripts:
----------------------------------------------------------------------------------------------------------
Upload.htm

<html>
<body>
<form enctype="multipart/form-data" action="/cgi-bin/upload.cgi"
method="post">
Enviar arquivo: <input name="userfile" size="30" type="file">
<BR><BR>
<input type="submit" value="Envia" name="Envia">
</form>
</body>
</html>
----------------------------------------------------------------------------------------------------------
Upload.CGI
#!/bin/sh

echo "<html><body><pre>"
# Limite
boundary=$(export | sed '/CONTENT_TYPE/!d;s/^.*dary=//;s/.$//')

# pegamos toda a entrada do POST e colocamos em VAR
VAR=$(sed -n '1,$p')

# pegamos o nome do arquivo que foi feito o upload
FILENAME=$(echo "$VAR" | sed -n '2!d;s/\(.*filename=\"\)\(.*\)\".*$/\2/;p')

# pegamos somente o conteudo do arquivo do upload
FILE=$(echo "$VAR" | sed -n "1,/$boundary/p" | sed '1,4d;$d')

# redirecionamos o conteudo do arquivo para um arquivo local no server
echo "$FILE" | sed '$d' > "/tmp/$FILENAME"

echo "</pre></body></html>"
----------------------------------------------------------------------------------------------------------

Qualquer opinião é bem vinda!

Atenciosamente,
Giuseppe


reply via email to

[Prev in Thread] Current Thread [Next in Thread]