lsof select only socket opened by an user - lsof

I can get the socket in listen state opened by an user with this code
lsof -sTCP:LISTEN -n -i -P |awk '$3 == "user" { print $0 }'
I would like to now if there is an option to lsof that also filter by user (or by process name by the way). I know that lsof has the -u option but this:
lsof -sTCP:LISTEN -n -i -P -u username
List all the files opened by user username, it doesn't filter the network connections (and it's slow).

Normally list options that are specifically stated are ORed
Try this instead:
lsof -u username -a -i -sTCP:LISTEN -nP

Related

Attach a tmux session over SSH and run a command

This works to attach a session with a specified name or create if it doesn't exist:
tmux new-session -A -s encode
but I need to add a command to run ie.
tmux new-session -A -s encode 'ls /home/user/'
You'll want to take a look at the tmux send-keys command. From the man
Send a key or keys to a window. Each argument key is the name of the key (such as C-a or npage ) to send; if the string is
not recognised as a key, it is sent as a series of characters. The -l flag disables key name lookup and sends the keys liter-
ally. All arguments are sent sequentially from first to last. The -R flag causes the terminal state to be reset.
In your case you can do
tmux new-session -d -A -s encode
tmux send-keys -t encode 'ls /home/users' C-m
tmux attach -t encode
C-m is the Enter key. The -d flag is to create the session, but not attach to it.

How to use a single grep command to search a pattern from different unix servers

For Example,
I have two servers namely A and B. I want to use a grep command in either A or B, which will search in both A and B servers and display the match.
You could use parallel ssh (pssh) for that.
See this command:
parallel-ssh -P -v -l root -A -H "192.168.1.1 192.168.1.2 192.168.1.3" "hostname"
Where hostname is the command to execute on each of the hosts. -P means print the output of the command, -l root means login with the user root, -A ask for the password and -H provides the list of hosts.
The output might look similar to this:
192.168.140.193: hostname1
192.168.140.194: hostname2
192.168.140.195: hostname3
[1] 11:18:17 [SUCCESS] 192.168.140.193
[2] 11:18:17 [SUCCESS] 192.168.140.194
[3] 11:18:17 [SUCCESS] 192.168.140.195
For those without access to parallel-ssh, try this:
#!/bin/bash
remotehost='hostnameA'
if [ `hostname` == 'hostnameA' ]
then
remotehost='hostnameB'
fi
{
grep whatever
ssh $remotehost grep whatever
}
The first part figures out what host you're on and which it needs to ssh into. The second part performs the command on both hosts and groups the output together.

scripting sftp with expect

I have to script an sftp-access with password-authentification. Unfortunately our customer can't create a key-authentification on the server we have to access.
All the sftp-Commands are generated and written in a temporary file (tmp.txt). Following command works fine on the command-line:
sftp OnlineRegTest_BS#ftp.b-n-c.ch < tmp.txt
The problems starts when I'd like to use "expect" because I have to script it and use a password.
EXPECTSCRIPT=`cat <<EOF
spawn sftp user#server < tmp.txt
expect "password"
send ${pass}
send "\r"
EOF`
expect -c "$EXPECTSCRIPT"
If I remove the "< tmp.txt" the connection will establish. But I need the commands from the tmp.txt. Here's the error-Message:
[root#xxx web]# ./transfer.sh
spawn sftp user#server < tmp.txt
usage: sftp [-1Cv] [-B buffer_size] [-b batchfile] [-F ssh_config]
[-o ssh_option] [-P sftp_server_path] [-R num_requests]
[-S program] [-s subsystem | sftp_server] host
sftp [[user#]host[:file [file]]]
sftp [[user#]host[:dir[/]]]
sftp -b batchfile [user#]host
send: spawn id exp6 not open
while executing
"send password"
Does someone have any ideas?
I also couldn't get it running with sftp -b... :-(
edit for #glenn jackman
EXPECTSCRIPT2=`cat <<EOF
spawn sh -c {sftp user#server < tmp.txt}
expect "password"
send ${pass}
send "\r"
expect "sftp>"
expect "sftp>"
.....
expect "sftp>"
expect "sftp>"
expect "sftp>"
EOF`
the tmp.txt looks like this:
cd d
put d/d1
cd ../e
put e/e1
put e/e2
cd ../f
put f/f1
Try spawning a shell to handle the redirection:
spawn sh -c {sftp user#example.com < tmp.txt}

Determine the process pid listening on a certain port

As the title says, I'm running multiple game servers, and every of them has the same name but different PID and the port number. I would like to match the PID of the server which is listening on certain port, and then I would like to kill this process. I need that in order to complete my bash script.
Is that even possible? Because it didn't find yet any solutions on the web.
Short version which you can pass to kill command:
lsof -i:80 -t
The -p flag of netstat gives you PID of the process:
netstat -l -p
*use sudo if showing - instead of PID
Edit: The command that is needed to get PIDs of socket users in FreeBSD is sockstat.
As we worked out during the discussion with #Cyclone, the line that does the job is:
sockstat -4 -l | grep :80 | awk '{print $3}' | head -1
netstat -p -l | grep $PORT and lsof -i :$PORT solutions are good but I prefer fuser $PORT/tcp extension syntax to POSIX (which work for coreutils) as with pipe:
pid=`fuser $PORT/tcp`
it prints pure pid so you can drop sed magic out.
One thing that makes fuser my lover tools is ability to send signal to that process directly (this syntax is also extension to POSIX):
$ fuser -k $port/tcp # with SIGKILL
$ fuser -k -15 $port/tcp # with SIGTERM
$ fuser -k -TERM $port/tcp # with SIGTERM
Also -k is supported by FreeBSD: http://www.freebsd.org/cgi/man.cgi?query=fuser
netstat -nlp should tell you the PID of what's listening on which port.
Syntax:
kill -9 $(lsof -t -i:portnumber)
Example:
To kill the process running at port 4200, run following command
kill -9 $(lsof -t -i:4200)
Tested in Ubuntu.
Since sockstat wasn't natively installed on my machine I hacked up stanwise's answer to use netstat instead..
netstat -nlp | grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:2000" | awk '{print $7}' | sed -e "s/\/.*//g""
I wanted to programmatically -- using only Bash -- kill the process listening on a given port.
Let's say the port is 8089, then here is how I did it:
badPid=$(netstat --listening --program --numeric --tcp | grep "::8089" | awk '{print $7}' | awk -F/ '{print $1}' | head -1)
kill -9 $badPid
I hope this helps someone else! I know it is going to help my team.
on windows, the netstat option to get the pid's is -o and -p selects a protocol filter, ex.:
netstat -a -p tcp -o

Problem with plink output

I'm using plink to run a command on a Unix remote machine.
The command is:
ls -1trd testegrep.txt |tail -1 |xargs tail -f| grep 's';
The way I'm sending this command is by using a file with a set of commands like:
plink.exe -ssh -t -l user -pw pwd tst.url.pt -m commands.out
When I run the command this way the plink does not receive any input. It seems that is waiting for input.
But if I run:
plink.exe -ssh -t -l user -pw pwd tst.url.pt "ls -1trd testegrep.txt |tail -1 |xargs tail -f| grep 's';"
I get the expected result.
I'm not using the plink with a file with the command because I choose so. I'm using a test automation software that allows me to run tests on remote hosts and this is the way the tool works.
Any thoughts on what is going wrong?
I tested the command you provided and it worked without problems.
Maybe the problem is related to:
The server's host key is not cached in the registry.
The path to the file is not correct.
The file is empty.
include server hostkey
most importantly, you need to include the unix profile using the -m paramater
You can include all your commands in the same file where the profile is kept also.
$Output = ((plink.exe -hostkey hostkey -l UNAME -i SSHKEY -P 22 -ssh server -batch -m PROFILE) | ? {$_ -ne ""})

Resources