encontreiPor aquide verificar se um host está acessível em uma determinada porta, porém estou interessado apenas no código de status do comando, portanto estou tentando algo assim:
[CptBartender@somewhere ~]$ <dev/tcp/host/port ; echo $?
0
Isso funciona bem se eu tentar uma porta aberta; no entanto, se eu verificar uma porta fechada, recebo:
[CptBartender@somewhere ~]$ <dev/tcp/host/blocked_port ; echo $?
-bash: connect: Connection refused
-bash: /dev/tcp/host/blocked_port: Connection refused
1
Agora, meu próximo passo foi tentar descartar as saídas do primeiro comando, então tentei:
[CptBartender@somewhere ~]$ <dev/tcp/host/blocked_port >/dev/null/ 2>&1; echo $?
-bash: connect: Connection refused
-bash: /dev/tcp/host/blocked_port: Connection refused
1
Mesma saída. Minhas perguntas são: por que o primeiro comando imprime qualquer saída e como evito que isso aconteça?
Responder1
Não é acomandoisso é impressão. Você não temqualquercomando - o < /dev/tcp/…
é apenas normalredirecionamento de entradae é processado pelo próprio shell.
(E não apenas isso, mas os redirecionamentos são processados da esquerda para a direita, então o <
redirecionamento é processadoantesaquele 2>&1
, então não poderia ser redirecionadode qualquer forma.)
Você pode contornar isso executando o "comando" em um subshell. Por exemplo:
( </dev/tcp/$host/$port ) 2>/dev/null
Na verdade, parece que neste caso um subshell não é necessário; um grupo de comandos funcionará mesmo se estiver dentro do mesmo processo – ainda força os redirecionamentos "externos" a serem processados primeiro:
{ </dev/tcp/$host/$port; } 2>/dev/null
Nota lateral: /dev/tcp
é um caminho mágico que é tratado pelo próprio bash - na verdade não existe no /dev do Linux, mas pode ser usado com redirecionamentos do bash. No entanto, esse truque não funcionará com o #!/bin/sh
, e ainda há uma chance de que não funcione com o bash em alguns sistemas mais antigos (que costumavam desabilitar esse recurso) ou em alguns sistemas não-Linux.