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

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:

Related

Close tmux session with a particular name

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

Unable to switch to root user after ssh into the instance using shell script

I have a scenario to automate the manual build update process via shell script on multiple VM nodes.
For the same, I am trying the below sample script to first ssh into the instance and then switch to root user to perform the further steps like copying the build to archives directory under /var and then proceed with the later steps.
Below is the sample script,
#!/bin/sh
publicKey='/path/to/publickey'
buildVersion='deb9.deb build'
buildPathToStore='/var/cache/apt/archives/'
pathToHomedir='/home'
script="whoami && pwd && ls -la && whoami && mv ${buildVersion} ${buildPathToStore} && find ${buildPathToStore} | grep deb9"
for var in "$#"
do
copyBuildPath="${publicKey} ${buildVersion} ${var}:/home/admin/"
echo "copy build ==>" ${copyBuildPath}
scp -r -i ${copyBuildPath}
ssh -i $publicKey -t $var "sudo su - & ${script}; " # This shall execute all commands as root
done
So the CLI stats for the above script are something like this
admin //this is the user check
/home/admin
total 48
drwxr-xr-x 6 admin admin 4096 Dec 6 00:28 .
drwxr-xr-x 6 root root 4096 Nov 17 14:07 ..
drwxr-xr-x 3 admin admin 4096 Nov 17 14:00 .ansible
drwx------ 2 admin admin 4096 Nov 23 18:26 .appdata
-rw------- 1 admin admin 5002 Dec 6 17:47 .bash_history
-rw-r--r-- 1 admin admin 220 May 16 2017 .bash_logout
-rw-r--r-- 1 admin admin 3506 Jun 14 2019 .bashrc
-rw-r--r-- 1 admin admin 675 May 16 2017 .profile
drwx------ 4 admin admin 4096 Nov 23 18:26 .registry
drwx------ 2 admin admin 4096 Jun 21 2019 .ssh
-rw-r--r-- 1 admin admin 0 Dec 6 19:42 testFile.txt
-rw------- 1 admin admin 2236 Jun 21 2019 .viminfo
admin
If I use sudo su -c and remove &
like:
ssh -i $publicKey -t $var "sudo su -c ${script}; "
Then for once whoami returns the user as root but the working directory still prints as /home/admin instead of /root
And the next set of commands are still accounted for admin user rather than the root. So the admin user do not have the privileges to move the build to archive directory and install the build.
Using & I want to ensure that the further steps are being done in the background.
Not sure how to proceed ahead with this. Good suggestions are most welcome right now :)
"sudo su - & ${script}; "
expands to:
sudo su - & whoami && pwd && ...
First sudo su - is run in the background. Then the command chain is executed.
sudo su -c ${script};
expands to:
sudo su -c whoami && pwd && ...
So first sudo su - whoami is executed, which runs whoami as root. Then if this command is successful, then pwd is executed. As normal user.
It is utterly hard to correctly pass commands to execute on remote site using ssh. It is increasingly hard to do it with sudo su - the command will be triple (or twice?) word splitted - one time by ssh, then by the shell, then by the shell run by sudo su.
If you do not need interactive communication, it's best to use a here document with -s shell option, something along (untested):
# DO NOT store commands to use in a variable.
# or if you do and you know what you are doing, properly quote it (printf "%q ") and run it via eval
script() {
set -euo pipefail
whoami
pwd
ls -la
whoami
mv "$buildVersion" "$buildPathToStore"
find "$buildPathToStore" | grep deb9
}
ssh ... "sudo bash -s" <<EOF
echo "Yay! anything here!"
echo "Note that here document delimiter is not quoted!"
$(
# safely import context to work with
# note how command substitution is executed on host side
declare -f script
# pass variables too!
declare -p buildVersion buildPathToStore buildPathToStore
)
script
EOF
When you use su alone it keeps you in your actual directory, if you use su - it simulates the root login.
You should write : su - root -c ${script};

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 $

Why my shell script not working with cron?

I have two shell scripts .
(working one)
$ cat script_nas.sh
#!/bin/bash
for i in `cat nas_filers`
do echo $i
touch /mnt/config-backup/nas_backup/$i.auditlog.0.$(date '+%Y%m%d')
ssh -o ConnectTimeout=5 root#$i rdfile /etc/configs/config_saved > /mnt/config-backup/nas_backup/$i.auditlog.0.$(date '+%Y%m%d')
done
other
(not working one)
$ cat script_san.sh
#!/bin/bash
for i in `cat san_filers`
do echo $i
touch /mnt/config-backup/san_backup/$i.auditlog.0.$(date '+%Y%m%d')
ssh -o ConnectTimeout=5 root#$i rdfile /etc/configs/config_saved > /mnt/config-backup/san_backup/$i.auditlog.0.$(date '+%Y%m%d')
done
Cron entries are:
$ crontab -l
Filers config save script
0 0 * * * /mnt/config-backup/script_san.sh
0 0 * * * /mnt/config-backup/script_nas.sh
0 0 * * * /mnt/config-backup/delete_file
Script script_san.sh is not working.
Outputs are like
SAN backup directory
san_backup]# ls -lart alln01-na-exch01a.cisco.com.auditlog*
-rw-r--r-- 1 root root 210083 Mar 1 22:24 alln01-na-exch01a.auditlog.0.20150301
[root#XXXXX san_backup]# pwd
/mnt/config-backup/san_backup
NAS backup directory
nas_backup]# ls -lart rcdn9-25f-filer43b.cisco.com.auditlog*
-rw-r--r-- 1 root root 278730 Feb 26 00:06 rcdn9-25f-filer43b.cisco.com.auditlog.0.20150226
-rw-r--r-- 1 root root 281612 Feb 27 00:17 rcdn9-25f-filer43b.cisco.com.auditlog.0.20150227
-rw-r--r-- 1 root root 284105 Feb 28 00:02 rcdn9-25f-filer43b.cisco.com.auditlog.0.20150228
-rw-r--r-- 1 root root 284101 Mar 1 00:02 rcdn9-25f-filer43b.cisco.com.auditlog.0.20150301
[root#XXXXXXX nas_backup]#
From cron logs I can see that cron is executing both the script but output for script_san.sh is not coming.
From my experience, most of the times script is working manually but not from crontab is because login scripts were not running. Try to add something like source ~/.bash_profile in the begging of script or first line in cron file. Did you try (for debugging) to run the script with at command?

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.

Resources