Suppressing output after SSH to another server

370 Views Asked by At

When I SSH to another server thare are some blurbs of text that always outputs when you log in. (wheather its SSH or just logging in to its own session)

"Authentification banner" is what it prints out every time i either scp a file over or SSH into it.

My code iterates thru a list of servers and sends a file, each time it does that it outputs a lot of text id like to suppress.

This code loops thru each server printing out what its doing.

for(my $j=0; $j < $#servName+1; $j++)
    {
        print "\n\nSending file: $fileToTransfer to \n$servName[$j]:$targetLocation\n\n";
        my $sendCommand = `scp $fileToTransfer $servName[$j]:$targetLocation`;
        print $sendCommand;
    }

But then it comes out like this:

Sending file: /JacobsScripts/AddAlias.pl to
denamap2:/release/jscripts


====================================================

  Welcome authorized users. This system is company
  property and unauthorized access or use is prohibited
  and may subject you to discipline, civil suit or
  criminal prosecution. To the extent permitted by law,
  system use and information may be monitored, recorded
  or disclosed. Using this system constitutes your
  consent to do so. You also agree to comply with applicable
  company procedures for system use and the protection of
  sensitive (including export controlled) data.

====================================================


Sending file: /JacobsScripts/AddAlias.pl to
denfpev1:/release/jscripts


====================================================

  Welcome authorized users. This system is company
  property and unauthorized access or use is prohibited
  and may subject you to discipline, civil suit or
  criminal prosecution. To the extent permitted by law,
  system use and information may be monitored, recorded
  or disclosed. Using this system constitutes your
  consent to do so. You also agree to comply with applicable
  company procedures for system use and the protection of
  sensitive (including export controlled) data.

====================================================

I havent tried much, i saw a few forums that mention taking the output into a file and then delete it but idk if thatll work for my situation.

2

There are 2 best solutions below

4
zdim On

NOTE   This answer assumes that on the system in question the ssh/scp messages go to STDERR stream (or perhaps even directly to /dev/tty), like they do on some systems I test with -- thus the question.

If not, then ikegami's answer of course takes care of it: just don't print the captured STDOUT. But even in that case, I also think that all ways shown here are better for capturing output (except for the one involving the shell), specially when both streams are needed.


These prints can be suppressed by configuring the server, or perhaps via a .hushlogin file, but then that clearly depends on the server management.

Otherwise, yes you can redirect standard streams to files or, better yet, to variables, what makes the overall management easier.

Using IPC::Run

use IPC::Run qw(run);

my ($file, $servName, $targetLocation) = ...
my @cmd = ("scp", $file, $servName, $targetLocation);

run \@cmd, '1>', \my $out, '2>', \my $err;

# Or redirect both to one variable
# run \@cmd, '>&', \my $out_err;

This mighty and rounded library allows great control over the external processes it runs; it provides almost a mini shell.

Or using the far simpler, and very handy Capture::Tiny

use Capture::Tiny qw(capture);

...    
my ($out, $err, $exit) = capture { system @cmd };

Here output can be merged using capture_merged. Working with this library is also clearly superior to builtins (qx, system, pipe-open).

In both cases then inspect $out and $err variables, what is far less cut-and-dry as error messages depend on your system. For some errors the library routines die/croak but for some others they don't but merely print to STDERR. It is probably more reliable to use other tools that libraries provide for detecting errors.

The ssh/scp "normal" (non-error) messages may print to either STDERR or STDOUT stream, or may even go directly to /dev/tty, so can be mixed with error messages.

Given that the intent seems to be to intersperse these scp commands with other prints then I'd recommend either of these two ways over the others below.


Another option, which I consider least satisfactory overall, is to use the shell to redirect output in the command itself, either to separate files

my ($out_file, $err_file) = ...
system("@cmd 2> $err_file 1> $out_file" ) == 0 
    or die "system(@cmd...) error: $?";  # see "system" in perldoc

or, perhaps for convenience, both streams can go to one file

system("@cmd > $out_err_file 2>&1" ) == 0  or die $?;

Then inspect files for errors and remove if there is nothing remarkable. Or, shell redirections can be used like in the question but to capture all output

my $out_and_err = qx(@cmd 2>&1);

Then examine the (possibly multiline) variable for errors.


Or, instead of dealing with individual commands we can redirect streams themselves to files for a duration of a larger part of the program

use warnings;
use strict;
use feature 'say';

# Save filehandles ('dup' them) so to be able to reopen later
open my $saveout, ">&STDOUT"  or die "Can't dup STDOUT: $!";
open my $saveerr, ">&STDERR"  or die "Can't dup STDERR: $!";#]]

my ($outf, $errf) = qw(stdout.txt stderr.txt);
open *STDOUT, ">", $outf or die "Can't redirect STDOUT to $outf: $!";
open *STDERR, ">", $errf or die "Can't redirect STDERR to $errf: $!";

my ($file, $servName, $targetLocation) = ...
my @cmd = ("scp", $file, $servName, $targetLocation);
system(@cmd) == 0 
    or die "system(@cmd) error: $?";  # see "system" in perldoc

# Restore standard streams when needed for normal output
open STDOUT, '>&', $saveout  or die "Can't reopen STDOUT: $!";
open STDERR, '>&', $saveerr  or die "Can't reopen STDERR: $!";

# Examine what's in the files (errors?)

I use system instead of qx (operator form of backticks) since there is no need for output from scp. Most of this is covered in open, and search SO for specifics.

It'd be nice to be able to reopen streams to variables but that doesn't work here


This is even prescribed ("allowed") by POSIX

/dev/tty

In each process, a synonym for the controlling terminal associated with the process group of that process, if any. It is useful for programs or shell procedures that wish to be sure of writing messages to or reading data from the terminal no matter how output has been redirected. It can also be used for applications that demand the name of a file for output, when typed output is desired and it is tiresome to find out what terminal is currently in use.

Courtesy of this superuser post, which has a substiantial discussion.

2
ikegami On

You are capturing the text, then printing it out using print $sendCommand;. You could simply remove that statement.