Iniciando
Nas configurações padrões do 
Apache, existe um diretório já pré-definido para scripts CGI rodarem. É o 
/usr/lib/cgi-bin/.
Irei criar um arquivo com o nome 
tutorial.sh. Nos scripts CGI, a saída dos scripts (
/dev/stdout e 
/dev/stderr), são enviadas para o cliente, as primeiras linhas do script serão o cabeçalho de resposta da requisição HTTP. 
Desse modo, podemos forçar o download de arquivos, fazer redirecionamentos, etc, a quebra de linha é que separa o que será o cabeçalho e o que será o resto da resposta.
Voltando ao arquivo 
tutorial.sh, dentro do arquivo, coloque as seguintes linhas:
 
#!/bin/bash
echo -e "Content-Type: text/plain\n"    # É o Cabeçalho, e a quebra de linha
echo "Hello World"    # Agora é o resto do request, o conteúdo que é exibido pelos navegadores.
 
Salve o arquivo e deixe as permissões como 775 (lembrando: r = 4, w = 2, x = 1).
Acesse o link: 
http://localhost/cgi-bin/tutorial.sh
E verá a mensagem: 
Hello World
Por padrão, o Apache já configura o cabeçalho de resposta. 
Se não quiser, você pode pôr no começo do script: 
echo -e "\n" ou printf "\n\n", e deixar que o Apache configure o cabeçalho, que normalmente, será algo parecido com isso:
 
HTTP/1.1 200 OK
Date: [...]
Server: Apache [...]
Content-Type: text/x-sh
Variáveis de ambiente
Em Shell Script, podemos ver quais são as variáveis de ambiente, usando o comando 
env. Se você digitar esse comando em um terminal, serão listadas diversas variáveis, como SHELL, HOME, USERNAME, etc.
Para listarmos as variáveis de ambiente no Apache, basta incluir no script o comando 
env, ficando da seguinte forma:
  
#!/bin/bash
echo -e "Content-Type: text/plain\n"
env
 
Salvei esse arquivo e acessei a página WEB usando o comando 
curl. O resultado, foi:
 curl -i localhost/cgi-bin/tutorial.sh
 HTTP/1.1 200 OK
 Date: Tue, 25 Mar 2014 00:24:04 GMT
 Server: Apache/2.2.22 (Debian)
 Vary: Accept-Encoding
 Transfer-Encoding: chunked
 Content-Type: text/plain
 
 SERVER_SIGNATURE=Apache/2.2.22 (Debian) 
 Server at localhost Port 80
 
 HTTP_USER_AGENT=curl/7.26.0
 SERVER_PORT=80
 HTTP_HOST=localhost
 DOCUMENT_ROOT=/var/www
 SCRIPT_FILENAME=/usr/lib/cgi-bin/tutorial.sh
 REQUEST_URI=/cgi-bin/tutorial.sh
 SCRIPT_NAME=/cgi-bin/tutorial.sh
 REMOTE_PORT=46944
 PATH=/usr/local/bin:/usr/bin:/bin
 PWD=/usr/lib/cgi-bin
 SERVER_ADMIN=webmaster@localhost
 HTTP_ACCEPT=*/*
 REMOTE_ADDR=127.0.0.1
 SHLVL=1
 SERVER_NAME=localhost
 SERVER_SOFTWARE=Apache/2.2.22 (Debian)
 QUERY_STRING=
 SERVER_ADDR=127.0.0.1
 GATEWAY_INTERFACE=CGI/1.1
 SERVER_PROTOCOL=HTTP/1.1
 REQUEST_METHOD=GET
 _=/usr/bin/env
   
Entendendo algumas variáveis:
-  HTTP_USER_AGENT :: User-agent que o cliente está usando. Pode ser usada para pegar informações sobre quem visita a sua página (navegador e sistema operacional).
-  REQUEST_METHOD :: Método de requisição utilizado, exemplo: GET, PUT, POST, OPTIONS, HEAD. Pode ser bem útil, pelo menos para mim, já foi.
-  QUERY_STRING :: Dados enviados via GET. Exemplo: localhost/cgi-bin/tutorial.sh?a=f&b=f (sendo: a = f e b = f).
-  REMOTE_ADDR :: IP do cliente.
   
Exemplo de utilização de variáveis de ambiente:
#!/bin/bash
cat <
Content-Type: text/plain
-----------------------------------
Seu User-agent => $HTTP_USER_AGENT
Seu I.P => $REMOTE_ADDR
-----------------------------------
A
 
  
Testando:
 curl localhost/cgi-bin/tutorial.sh
 -----------------------------------
 Seu User-agent => curl/7.26.0
 Seu I.P => 127.0.0.1
 -----------------------------------