Close tmux session with a particular name - bash

I would like to have a command that closes all tmux session which name corresponds to a pattern. The pattern, in the language of regex, is nn\d+
I feel that I should be able to use a combination of grep and xargs.
I tried with
tmux ls | grep -P "nn\d+" | ..
but I am not sure how to use xargs here, that is: I am not sure how to refer to only the name part of the matched string, and to one string at the time.
To be more precise, the output of tmux ls is something like:
1: 1 windows (created Thu Mar 25 12:49:17 2021)
2: 1 windows (created Thu Mar 25 12:50:20 2021)
nn312133: 1 windows (created Thu Mar 25 12:53:54 2021)
nn3123: 1 windows (created Thu Mar 25 12:53:52 2021)
The output from grep is:
nn312133: 1 windows (created Thu Mar 25 12:53:54 2021)
nn3123: 1 windows (created Thu Mar 25 12:53:52 2021)
I should need to pipe nn312133 and nn3123 into tmux kill-session -t $x
Any idea? Thanks

Use grep -Po to make grep only print out the matched part instead of the whole line.

The answer is tmux ls | grep -Po "nn\d+" | xargs -n1 tmux kill-session -t

Related

linux touch relative time giving wrong result

I'm using bash touch to change the date and time of a file. It works correctly if I simply specify the date and time. If, however, I use a relative time I get unexpected behavior.
$ date -R -r test.txt
Sat, 28 May 2022 02:56:22 -0400
$ touch -d '27 May 2022 05:31:12' test.txt
$ date -R -r test.txt
Fri, 27 May 2022 05:31:12 -0400
$ touch -d '27 May 2022 05:31:12 - 1 hour' test.txt
$ date -R -r test.txt
Fri, 27 May 2022 03:31:12 -0400
$ touch -d "27 May 2022 05:31:12 + 1 hour" test.txt
$ date -R -r test.txt
Fri, 27 May 2022 01:31:12 -0400
Note that although I asked for 1 hour earlier and then 1 hour later, it gave 2 hours earlier and 4 hours earlier respectively.
Any help would be appreciated.
When you do your touch, you do no specify the timezone. If you do, all your date arithmetic works ok.
EX:
$ touch -d '27 May 2022 05:31:12' test.txt
$ date -R -r test.txt
Fri, 27 May 2022 05:31:12 -0400
$
$ touch -d '27 May 2022 05:31:12 -0400 - 1 hour' test.txt
$ date -R -r test.txt
Fri, 27 May 2022 04:31:12 -0400

(CRON) info (No MTA installed, discarding output) sent message telegram

i'm make a new shell script crontab notify to telegram but the message doesn't received
environment
ubuntu 16.04
uname -n >> text.txt
while read p; do
adb -s "$p" shell getprop ro.product.manufacturer >> text.txt
adb -s "$p" shell dumpsys battery | grep level >> text.txt
adb -s "$p" shell getprop ro.product.model >> text.txt
adb -s "$p" shell dumpsys battery | grep health >> text.txt
TEXT=$(cat text.txt)
curl -X POST https://api.telegram.org/bot<token>/sendMessage -d chat_id=<chat id> -d text="$TEXT"
rm text.txt
done <info.txt
i expect the message can be received in telegram
this log cron
cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-03-25 17:53:44 WIB; 11min ago
Docs: man:cron(8)
Main PID: 14599 (cron)
Tasks: 1
Memory: 3.3M
CPU: 229ms
CGroup: /system.slice/cron.service
└─14599 /usr/sbin/cron -f
Mar 25 18:02:01 -Latitude-3490 CRON[14811]: pam_unix(cron:session): session opened for user root by (uid=0)
Mar 25 18:02:01 -Latitude-3490 CRON[14812]: (root) CMD (sh /home/asd/device_info.sh)
Mar 25 18:02:01 -Latitude-3490 CRON[14811]: pam_unix(cron:session): session closed for user root
Mar 25 18:03:01 -Latitude-3490 CRON[14857]: pam_unix(cron:session): session opened for user root by (uid=0)
Mar 25 18:03:01 -Latitude-3490 CRON[14858]: (root) CMD (sh /home/asd/device_info.sh)
Mar 25 18:03:01 -Latitude-3490 CRON[14857]: pam_unix(cron:session): session closed for user root
Mar 25 18:04:01 -Latitude-3490 CRON[14866]: pam_unix(cron:session): session opened for user root by (uid=0)
Mar 25 18:04:01 -Latitude-3490 CRON[14867]: (root) CMD (sh /home/asd/device_info.sh)
Mar 25 18:05:01 -Latitude-3490 CRON[14879]: pam_unix(cron:session): session opened for user root by (uid=0)
Mar 25 18:05:01 -Latitude-3490 CRON[14880]: (root) CMD (sh /home/asd/device_info.sh)
first of all see: https://unix.stackexchange.com/a/150556
this is quick issue for your case.
for one mobile device serial number:
#!/bin/bash
SERIAL="XX-XXXXXXXXXXXXXXXXXXXXXXXX"
TOKEN="XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
CHATID="XXXXXXXXX"
# stuff
MSG="*server hostname:*
$(uname -n)
*mobile device info:*
$(adb -s "$SERIAL" shell getprop ro.product.manufacturer)
$(adb -s "$SERIAL" shell getprop ro.product.model)
$(adb -s "$SERIAL" shell dumpsys battery | grep -Eo '(level|health).*' )"
curl -s https://api.telegram.org/bot"$TOKEN"/sendMessage \
-d "chat_id=$CHATID&text=$MSG&parse_mode=markdown" > /dev/null
# end stuff
for whitespace separated serials in devices.txt file you should add
...
for SERIAL in $(cat devices.txt)
do
# stuff
...
...
# end stuff
done
add job to crontab
* * * * * exec /root/get_device_info
result:

Run function on every prompt line with .bash_profile editing

I have the following PS1 command in my .bash_profile:
PS1="$(svn info 2>&1 | grep 'Relative URL' | awk '{print $NF}')"
So that the output of this command is presented in the prompt line.
But it is run once I start the terminal and it just stays there, instead of changing while I navigate through my directories. So it runs once and is left there.
How can I make it change as I am navigating my directories?
PROMPT_COMMAND
If set, the value is executed as a command prior to issuing each
primary prompt.
$ PROMPT_COMMAND=date
Sun Feb 21 13:35:21 EST 2016
$ echo a
a
Sun Feb 21 13:35:23 EST 2016
$ echo b
b
Sun Feb 21 13:35:24 EST 2016
$ PROMPT_COMMAND='PS1=`date +%H:%M`\ $\ '
13:35 $ sleep 60
13:36 $

How to preserve the format of command output after it is assigned to a variable in csh?

Now I want to record all user's login messages in freeBSD, so I type last -f /var/log/utx.log in freeBSD to see the log.
The output format is:
brandboat pts/1 xxx.xxx.xxx.xxx Sat Nov 1 11:28 still logged in
brandboat pts/0 xxx.xxx.xxx.xxx Sat Nov 1 11:21 still logged in
root ttyv0 Sat Nov 1 11:16 still logged in
brandboat pts/1 xxx.xxx.xxx.xxx Sat Nov 1 11:11 - 11:25 (00:13)
And I try to copy all of these message in to a variable:
set aaa= `last -f /var/log/utx.log`
echo $aaa
the output is:
brandboat pts/1 xxx.xxx.xxx.xxx Sat Nov 1 11:28 still logged in brandboat pts/0 xxx.xxx.xxx.xxx Sat Nov 1 11:21 still logged in root ttyv0 Sat Nov 1 11:16 still logged in brandboat pts/1 xxx.xxx.xxx.xxx Sat Nov 1 11:11 - 11:25 (00:13)
As you can see, it doesn't keep the original format from the command output. How do I keep it in csh?
This is black magic but it works:
$ csh
% set g=`ls | sed -s ':a;N;$\\!ba;s/\n/\\n/g'`
% echo "$g"
% /bin/echo -e "$g"
The idea is to change the newlines by \n using sed. I used this trick to get it. Note that I had to double escape label !ba to tell csh that it is not an event.
You may replace ls by last -f /var/log/utx.log to check if it works for you.

display a line every two line (osX) zsh

I'd to display every two line, a line from a file. I've seen the sed -n 'f~d' awk and perl method. But the sed one doesn't work on osX (As I understood) and the two others are are interpreted languages which i can't use.
Can you help me ?
Here's an exemple :
output before :
-rw-r--r-- 1 mfassi-f 2013 22 Jul 17 12:36 test.sh
-rw-r--r-- 1 mfassi-f 2013 29 Jul 17 12:30 test1.sh
-rw-r--r-- 1 mfassi-f 2013 22 Jul 17 12:36 test2.sh
-rw-r--r-- 1 mfassi-f 2013 29 Jul 17 12:30 test3.sh
-rw-r--r-- 1 mfassi-f 2013 22 Jul 17 12:36 test4.sh
-rw-r--r-- 1 mfassi-f 2013 29 Jul 17 12:30 test5.sh
-rw-r--r-- 1 mfassi-f 2013 22 Jul 17 12:36 test6.sh
output after :
-rw-r--r-- 1 mfassi-f 2013 29 Jul 17 12:30 test1.sh
-rw-r--r-- 1 mfassi-f 2013 29 Jul 17 12:30 test3.sh
-rw-r--r-- 1 mfassi-f 2013 29 Jul 17 12:30 test3.sh
-rw-r--r-- 1 mfassi-f 2013 29 Jul 17 12:30 test5.sh
Here are two answers. One for a file, and one for command-line input.
['cause the question's changed ever so slightly, but these two seemed too similar to put as independent answers].
You can use zsh, ls, cut and paste to do this in a for loop. It's not the cleanest solution, but it does work (surprisingly).
for file in `ls -1 | paste - - | cut -f 1`
do
ls -l -d $file
done
We take the output of ls -1, then extract every second filename. (The way ls chooses to sort the files will have an impact here). Then, we do ls -l -d on each of these files. -d is necessary to stop ls from showing us the contents of $file, if $file is a directory. (Not sure if this is OS X specific, or if that's default POSIX ls behaviour).
Second answer: display every second line from a file.
If you're after a mostly zsh solution, you could do something like the following:
$ jot 8 0 7 >> sample.txt # Generate some numbers.
$ count=0 # Storage variable
$ for i in `cat sample.txt`
do
if [ $(( $count % 2 )) -eq 0 ] ; then
echo $i
fi
count=`expr $count + 1`
done
This displays every second line.
Notes:
- This leaves a variable count in your session afterwards (it's not clean).
- This fails badly if sample.txt does not contain a single word per line.
- I'm almost sure that the modulus comparison I do isn't the most efficient: I grabbed it from here.
- I say it's mostly zsh because it does rely on cat, but I'm not sure how to avoid that.
The OS X version of sed is frustrating. Using sed -n '0~2p' <filename> doesn't work because, in the BSD sed, -n does something different:
-n
By default, each line of input is echoed to the standard output after all of the commands have been applied to it. The -n option suppresses this behavior.
I'd highly recommend installing GNU sed, which can be done using Homebrew:
brew install gnu-sed
And then you can use:
gsed -n '0~2p' filename # Display the 2nd, 4th etc
gsed -n '1~2p' filename # Display the 1st, 3rd etc.

Resources