Related
I'm trying to detect the presence of iTerm2 and if I run the following in iTerm2 (echo -n $'\e[5n'; read -s -t 0.1 line; printf '%q\n' "$line") the terminal responds with $'\033'\[ITERM2\ 3.2.1n$'\033'\[0n
However, if I am running a tmux session in the terminal, then tmux responds and gives me nothing.
Any idea how I can ask tmux to query the physical terminal to report its status?
Footnotes
Here is a description of [5n in the tmux source: https://github.com/tmux/tmux/blob/486ce9b09855ae30a2bf5e576cb6f7ad37792699/tools/ansicode.txt#L577
This might be iTerm2 only, since I haven't seen a response on any other terminal
According to ft in freenode's #tmux (and as seen in this Super User answer), you can use:
'\ePtmux;\e" STUFF_FOR_THE_TERMINAL_HERE "\e\\'
So, it would be something like:
echo -n $'\ePtmux;\e\e[5n\e\\'
I know that I can run tmux -V to find the version of tmux that is in my PATH, but how can I get the version of tmux that is currently running?
As pointed out in a comment, tmux -V returns the version:
$ tmux -V
tmux 3.0a
Tested on Centos 7 and OSX 12.5.
Most obvious, but not 100% correct way is to execute this command in console
$ tmux -V
and receive output like this tmux 2.9a with version of tmux INSTALLED, not currently running.
In 99% cases it is enough, but there can be subtle nuances.
Command tmux -V will return version of tmux installed at /usr/bin/tmux or any other directory inside your PATH variable. If you have tmux already running, it is possible that tmux can be started from binary of other version and from different place (for example, tmux can be started from /home/user/bin/tmux).
In this case, you have to call
$ ps -e | grep tmux
to see PID of all tmux processes currently running. It will output something like this
[vodolaz095#ivory ~]$ ps -e | grep tmux
19699 pts/0 00:00:00 tmux: client
19701 ? 00:00:00 tmux: server
Here, number 19701 depicts process id (PID) of currently running tmux server.
After getting PID of tmux server, you can ran command
$ lsof -p 19701
to get information about CURRENTLY RUNNING tmux server process (in my case its 19701) that will output something like this (Figure 1)
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
tmux:\x20 19701 vodolaz095 cwd DIR 8,33 4096 22544385 /home/vodolaz095
tmux:\x20 19701 vodolaz095 rtd DIR 8,1 4096 2 /
tmux:\x20 19701 vodolaz095 txt REG 8,1 677760 3675332 /usr/bin/tmux
tmux:\x20 19701 vodolaz095 mem REG 8,1 6406312 131327 /var/lib/sss/mc/group
as you can see, tmux currently running was executed from binary placed in /usr/bin/tmux.
Or, you can call one liner
lsof -p `pgrep 'tmux: server'`
to achieve the same output as Figure 1
After you get path to tmux binary CURRENTLY RUNNING, (in my case, it was /usr/bin/tmux), you can execute this binary with flag -V to get its version
/usr/bin/tmux -V
or, if tmux was installed by limited user into /home/user/bin/tmux,
/home/user/bin/tmux -V
And, as result, you'll get version of tmux currently running, not the one, that was installed.
To get the version of the tmux server you can use display-message.
./tmux2.3 display-message -p "#{version}"
Will show the version of the server (2.7 in my case)
-p will direct the output of stdout so you can script with it and {version} can be anything from the FORMATS section in the man page.
The following will give you the executable of your tmux server, on linux:
realpath /proc/$(tmux display-message -p "#{pid}")/exe
And on macos, proc_pidpath can be used, see https://stackoverflow.com/a/8149380
To find the actual version of the tmux that is running, you have to find the PID of the tmux:
pgrep tmux
With this info, you can check the version by running:
lsof -p $tmuxPID | grep REG | grep -i -e deleted -e "tmux$"
If there is not a (deleted) next to the tmux file listed, you can just run that file with a -V.
If it results in files that are "(deleted)", you are running an old, uninstalled version. If you are on linux, you can figure out what it is by running:
/proc/$tmuxPID/exe -V`
If you are on OS X, you are stuck with whatever information is in the path to the filename, possibly something like Cellar/tmux/<version number>/bin/tmux.
You can combine many of these steps into the following one-liner:
for tmuxPID in $(pgrep tmux); do lsof -p $tmuxPID | grep REG | grep -i -e deleted -e "tmux$"; done
Or if you are on Linux, this always works:
for tmuxPID in $(pgrep tmux); do /proc/$tmuxPID/exe -V; done
I have two unix machines, both running AIX 5.3
My $HOME is mounted on machine1.
Using NFS, login machine2 will go to the same $HOME
I login machine2 first, then machine1.
Both using telnet.
The 2 sessions will share the same .sh_history file.
I found out that the fc -l behavior very strange.
In machine2, I issue the commands in telnet:
fc -l
ksh fc -l
Both give the same output.
In machine1,
fc -l
ksh fc -l
give DIFFERENT results
The result for ksh fc -l
is the same as /usr/bin/fc -l
Also, when I run a script like this:
#!/usr/bin/ksh
fc -l
The result is same as /usr/bin/fc -l
Could anyone tell me what happened?
Alvin SIU
Ah, wisdom of the ancients... (Since this post is over a year old.)
Anyway, I just encountered this problem in Solaris 10. Issue seems to be this: When you define a function in /etc/profile, or in any file called by /etc/profile, your HISTFILE variable gets ignored by the Korn shell, and the shell instead uses ".sh_history" when accessing its history. Not sure why this is.
Result is that you see other root shell's commands. You can test it with :
lsof -p $$
or
cat /proc/$$/fd/63
It's possible that the login shell is not ksh or that $HISTFILE is being reset. One thing you can do is echo $HISTFILE in the various situations and see if it's different. Another thing to check is to see what shell you're in using ps.
Bash (default $HOME/.bash_history), for example, will have a different $HISTFILE than ksh (default $HOME/.sh_history).
Another possible reason for the difference is that the builtin fc may be able to see in-memory history that hasn't been written to disk yet (which the external /usr/bin/fc wouldn't be able to see). If this is true, it may be version dependent. Bash, for example, doesn't write history to the file until the shell exits. Ksh (at least the version I'm using) writes it immediately.
Sending a message from the Unix command line using mail TO_ADDR results in an email from $USER#$HOSTNAME. Is there a way to change the "From:" address inserted by mail?
For the record, I'm using GNU Mailutils 1.1/1.2 on Ubuntu (but I've seen the same behavior with Fedora and RHEL).
[EDIT]
$ mail -s Testing chris#example.org
Cc:
From: foo#bar.org
Testing
.
yields
Subject: Testing
To: <chris#example.org>
X-Mailer: mail (GNU Mailutils 1.1)
Message-Id: <E1KdTJj-00025z-RK#localhost>
From: <chris#localhost>
Date: Wed, 10 Sep 2008 13:17:23 -0400
From: foo#bar.org
Testing
The "From: foo#bar.org" line is part of the message body, not part of the header.
In my version of mail ( Debian linux 4.0 ) the following options work for controlling the source / reply addresses
the -a switch, for additional headers to apply, supplying a From: header on the command line that will be appended to the outgoing mail header
the $REPLYTO environment variable specifies a Reply-To: header
so the following sequence
export REPLYTO=cms-replies#example.com
mail -aFrom:cms-sends#example.com -s 'Testing'
The result, in my mail clients, is a mail from cms-sends#example.com, which any replies to will default to cms-replies#example.com
NB: Mac OS users: you don't have -a , but you do have $REPLYTO
NB(2): CentOS users, many commenters have added that you need to use -r not -a
NB(3): This answer is at least ten years old(1), please bear that in mind when you're coming in from Google.
On Centos 5.3 I'm able to do:
mail -s "Subject" user#address.com -- -f from#address.com < body
The double dash stops mail from parsing the -f argument and passes it along to sendmail itself.
GNU mailutils's 'mail' command doesn't let you do this (easily at least). But If you install 'heirloom-mailx', its mail command (mailx) has the '-r' option to override the default '$USER#$HOSTNAME' from field.
echo "Hello there" | mail -s "testing" -r sender#company.com recipient#company.com
Works for 'mailx' but not 'mail'.
$ ls -l /usr/bin/mail
lrwxrwxrwx 1 root root 22 2010-12-23 08:33 /usr/bin/mail -> /etc/alternatives/mail
$ ls -l /etc/alternatives/mail
lrwxrwxrwx 1 root root 23 2010-12-23 08:33 /etc/alternatives/mail -> /usr/bin/heirloom-mailx
mail -s "$(echo -e "This is the subject\nFrom: Paula <johny#paula.com>\n
Reply-to: 1232564#yourserver.com\nContent-Type: text/html\n")"
milas.josh#gmail.com < htmlFileMessage.txt
the above is my solution....any extra headers can be added just after the from and before the reply to...just make sure you know your headers syntax before adding them....this worked perfectly for me.
Plus it's good to use -F option to specify Name of sender.
Something like this:
mail -s "$SUBJECT" $MAILTO -- -F $MAILFROM -f ${MAILFROM}#somedomain.com
Or just look at available options:
http://www.courier-mta.org/sendmail.html
It's also possible to set both the From name and from address using something like:
echo test | mail -s "test" example#example.com -- -F'Some Name<example2#example.com>' -t
For some reason passing -F'Some Name' and -fexample2#example.com doesn't work, but passing in the -t to sendmail works and is "easy".
I derived this from all the above answers. Nothing worked for me when I tried each one of them. I did lot of trail and error by combining all the above answers and concluded on this. I am not sure if this works for you but it worked for me on Ununtu 12.04 and RHEL 5.4.
echo "This is the body of the mail" | mail -s 'This is the subject' '<receiver-id1#email.com>,<receiver-id2#email.com>' -- -F '<SenderName>' -f '<from-id#email.com>'
One can send the mail to any number of people by adding any number of receiver id's and the mail is sent by SenderName from from-id#email.com
Hope this helps.
Here are some options:
If you have privelige enough, configure sendmail to do rewrites with the generics table
Write the entire header yourself (or mail it to yourself, save the entire message with all headers, and re-edit, and send it with rmail from the command line
Send directly with sendmail, use the "-f" command line flag and don't include your "From:" line in your message
These aren't all exactly the same, but I'll leave it to you look into it further.
On my portable, I have sendmail authenticating as a client to an outgoing mail server and I use generics to make returning mail come to another account. It works like a charm.
I aggregate incoming mail with fetchmail.
I don't know if it's the same with other OS, but in OpenBSD, the mail command has this syntax:
mail to-addr ... -sendmail-options ...
sendmail has -f option where you indicate the email address for the FROM: field. The following command works for me.
mail recepient#example.com -f from#example.com
On CentOS this worked for me:
echo "email body" | mail -s "Subject here" -r from_email_address email_address_to
Thanks BEAU
mail -s "Subject" user#address.com -- -f from#address.com
I just found this and it works for me. The man pages for mail 8.1 on CentOS 5 doesn't mention this. For -f option, the man page says:
-f Read messages from the file named by the file operand instead of the system mailbox. (See also folder.) If no file operand is specified, read messages from mbox instead of the system mailbox.
So anyway this is great to find, thanks.
On Debian 7 I was still unable to correctly set the sender address using answers from this question, (would always be the hostname of the server) but resolved it this way.
Install heirloom-mailx
apt-get install heirloom-mailx
ensure it's the default.
update-alternatives --config mailx
Compose a message.
mail -s "Testing from & replyto" -r "sender <sender#example.com>" -S replyto="sender#example.com" recipient#example.net < <(echo "Test message")
echo "body" | mail -S from=address#foo.com "Hello"
-S lets you specify lots of string options, by far the easiest way to modify headers and such.
echo "test" | mailx -r fake#example.com -s 'test' email#example.com
It works in OpenBSD.
this worked for me
echo "hi root"|mail -rsawrub#testingdomain.org -s'testinggg' root
On CentOS 5.5, the easiest way I've found to set the default from domain is to modify the hosts file. If your hosts file contains your WAN/public IP address, simply modify the first hostname listed for it. For example, your hosts file may look like:
...
11.22.33.44 localhost default-domain whatever-else.com
...
To make it send from whatever-else.com, simply modify it so that whatever-else.com is listed first, for example:
...
11.22.33.44 whatever-else.com localhost default-domain
...
I can't speak for any other distro (or even version of CentOS) but in my particular case, the above works perfectly.
What allowed me to have a custom reply-to address on an Ubuntu 16.04 with UTF-8 encoding and a file attachment:
Install the mail client:
sudo apt-get install heirloom-mailx
Edit the SMTP configuration:
sudo vim /etc/ssmtp/ssmtp.conf
mailhub=smtp.gmail.com:587
FromLineOverride=YES
AuthUser=???#gmail.com
AuthPass=???
UseSTARTTLS=YES
Send the mail:
sender='send#domain.com'
recipient='recipient#domain.com'
zipfile="results/file.zip"
today=`date +\%d-\%m-\%Y`
mailSubject='My subject on the '$today
read -r -d '' mailBody << EOM
Find attached the zip file.
Regards,
EOM
mail -s "$mailSubject" -r "Name <$sender>" -S replyto="$sender" -a $zipfile $recipient < <(echo $mailBody)
None of the above solutions are working for me...
#!/bin/bash
# Message
echo "My message" > message.txt
# Mail
subject="Test"
mail_header="From: John Smith <john.smith#example.com>"
recipients="recipient#example.com"
#######################################################################
cat message.txt | mail -s "$subject" -a "$mail_header" -t "$recipients"
I recent versions of GNU mailutils mail it is simply mail -r foo#bar.com.
Looking at the raw sent mail, it seems to set both Return-Path: <foo#bar.com> and From: foo#bar.com.
The answers provided before didn't work for me on CentOS5. I installed mutt. It has a lot of options. With mutt you do this this way:
export EMAIL=myfrom#example.com
export REPLYTO=myreplyto#example.com
mutt -s Testing chris#example.org
So I log into a Solaris box, try to start Apache, and find that there is already a process listening on port 80, and it's not Apache. Our boxes don't have lsof installed, so I can't query with that. I guess I could do:
pfiles `ls /proc` | less
and look for "port: 80", but if anyone has a better solution, I'm all ears! Even better if I can look for the listening process without being root. I'm open to both shell and C solutions; I wouldn't mind having a little custom executable to carry with me for the next time this comes up.
Updated: I'm talking about generic installs of solaris for which I am not the administrator (although I do have superuser access), so installing things from the freeware disk isn't an option. Obviously neither are using Linux-specific extensions to fuser, netstat, or other tools. So far running pfiles on all processes seems to be the best solution, unfortunately. If that remains the case, I'll probably post an answer with some slightly more efficient code that the clip above.
I found this script somewhere. I don't remember where, but it works for me:
#!/bin/ksh
line='---------------------------------------------'
pids=$(/usr/bin/ps -ef | sed 1d | awk '{print $2}')
if [ $# -eq 0 ]; then
read ans?"Enter port you would like to know pid for: "
else
ans=$1
fi
for f in $pids
do
/usr/proc/bin/pfiles $f 2>/dev/null | /usr/xpg4/bin/grep -q "port: $ans"
if [ $? -eq 0 ]; then
echo $line
echo "Port: $ans is being used by PID:\c"
/usr/bin/ps -ef -o pid -o args | egrep -v "grep|pfiles" | grep $f
fi
done
exit 0
Edit: Here is the original source:
[Solaris] Which process is bound to a given port ?
Here's a one-liner:
ps -ef| awk '{print $2}'| xargs -I '{}' sh -c 'echo examining process {}; pfiles {}| grep 80'
'echo examining process PID' will be printed before each search, so once you see an output referencing port 80, you'll know which process is holding the handle.
Alternatively use:
ps -ef| grep $USER|awk '{print $2}'| xargs -I '{}' sh -c 'echo examining process {}; pfiles {}| grep 80'
Since 'pfiles' might not like that you're trying to access other user's processes, unless you're root of course.
Mavroprovato's answer reports more than only the listening ports. Listening ports are sockets without a peer. The following Perl program reports only the listening ports. It works for me on SunOS 5.10.
#! /usr/bin/env perl
##
## Search the processes which are listening on the given port.
##
## For SunOS 5.10.
##
use strict;
use warnings;
die "Port missing" unless $#ARGV >= 0;
my $port = int($ARGV[0]);
die "Invalid port" unless $port > 0;
my #pids;
map { push #pids, $_ if $_ > 0; } map { int($_) } `ls /proc`;
foreach my $pid (#pids) {
open (PF, "pfiles $pid 2>/dev/null |")
|| warn "Can not read pfiles $pid";
$_ = <PF>;
my $fd;
my $type;
my $sockname;
my $peername;
my $report = sub {
if (defined $fd) {
if (defined $sockname && ! defined $peername) {
print "$pid $type $sockname\n"; } } };
while (<PF>) {
if (/^\s*(\d+):.*$/) {
&$report();
$fd = int ($1);
undef $type;
undef $sockname;
undef $peername; }
elsif (/(SOCK_DGRAM|SOCK_STREAM)/) { $type = $1; }
elsif (/sockname: AF_INET[6]? (.*) port: $port/) {
$sockname = $1; }
elsif (/peername: AF_INET/) { $peername = 1; } }
&$report();
close (PF); }
#!/usr/bin/bash
# This is a little script based on the "pfiles" solution that prints the PID and PORT.
pfiles `ls /proc` 2>/dev/null | awk "/^[^ \\t]/{smatch=\$0;next}/port:[ \\t]*${1}/{print smatch, \$0}{next}"
From Solaris 11.2 onwards you can indeed do this with the netstat command. Have a look here. The -u switch is what you are looking for.
If you are on a lower version of Solaris then - as others have pointed out - the Solaris way of doing this is some kind of script wrapper around pfiles command. Beware though that pfiles command halts the process for a split second in order to inspect it. For 99.9% of processes this is unimportant. Unfortunately we have a process that will give a core dump if it is hit with a pfiles command so we are a bit cautious about using the command. Your situation may be totally different if you are in the 99.9%, meaning you can safely use the pfiles command.
netstat on Solaris will not tell you this, nor will older versions of lsof, but if you download and build/install a newer version of lsof, this can tell you that.
$ lsof -v
lsof version information:
revision: 4.85
latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
configuration info: 64 bit kernel
constructed: Fri Mar 7 10:32:54 GMT 2014
constructed by and on: user#hostname
compiler: gcc
compiler version: 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
8<- - - - ***SNIP*** - - -
With this you can use the -i option:
$ lsof -i:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 521 root 3u IPv6 0xffffffff89c67580 0t0 TCP *:ssh (LISTEN)
sshd 5090 root 3u IPv6 0xffffffffa8668580 0t322598 TCP host.domain.com:ssh->21.43.65.87:52364 (ESTABLISHED)
sshd 5091 johngh 4u IPv6 0xffffffffa8668580 0t322598 TCP host.domain.com:ssh->21.43.65.87:52364 (ESTABLISHED)
Which shows you exactly what you're asking for.
I had a problem yesterday with a crashed Jetty (Java) process, which only left 2 files in its /proc/[PID] directory (psinfo & usage).
pfiles failed to find the process (because the date it needed was not there)
lsof found it for me.
You might not want to, but your best bet is to grab the sunfreeware CD and install lsof.
Other than that, yes you can grovel around in /proc with a shell script.
I think the first answer is the best
I wrote my own shell script developing this idea :
#!/bin/sh
if [ $# -ne 1 ]
then
echo "Sintaxis:\n\t"
echo " $0 {port to search in process }"
exit
else
MYPORT=$1
for i in `ls /proc`
do
pfiles $i | grep port | grep "port: $MYPORT" > /dev/null
if [ $? -eq 0 ]
then
echo " Port $MYPORT founded in $i proccess !!!\n\n"
echo "Details\n\t"
pfiles $i | grep port | grep "port: $MYPORT"
echo "\n\t"
echo "Process detail: \n\t"
ps -ef | grep $i | grep -v grep
fi
done
fi
Most probly sun's administrative server..
It's usually bundled along with sun's directory and a few other webmin-ish stuff that is in the default installation
This is sort of an indirect approach, but you could see if a website loads on your web browser of choice from whatever is running on port 80. Or you could telnet to port 80 and see if you get a response that gives you a clue as to what is running on that port and you can go shut it down. Since port 80 is the default port for http traffic chances are there is some sort of http server running there by default, but there's no guarantee.
If you have access to netstat, that can do precisely that.