get second imei number through adb shell - adb

I was able to get one imei number through adb shell with command
adb shell service call iphonesubinfo 1
But device has two imei numbers ,
How to get second imei number through adb shell
The output of adb shell service call iphonesubinfo 1 is as below (which is inbetween quotes)
Result:
Parcel(
0x00000000: 00000000 0000000f 00320031 00340033 '........1.2.3.4.'
0x00000010: 00360035 00380037 00300039 00380039 '5.6.7.8.9.0.9.8.'
0x00000020: 00360037 00000035 '7.6.5... ')
imei=123456789098765
Help me to find second imei......

Yes, you can get both IMEI with service call iphonesubinfo.
Though the order in which they are fetch is not always definite in my experience, but you can always fetch both and compare to one if you need to.
/system/bin/service call iphonesubinfo 3 i32 1 | cut -d\' -f2 | sed -e 's/[^0-9]//g' | tr -d '\n'
/system/bin/service call iphonesubinfo 3 i32 2 | cut -d\' -f2 | sed -e 's/[^0-9]//g' | tr -d '\n'
You can substitute /system/bin/service with adb shell service if you are running from adb and not from device shell.

Related

Save one line of `top`, `htop` or `intel_gpu_top` outputs into a Bash array

I want to save 1 line from the output of top into a Bash array to later access its components:
$ timeout 1 top -d 2 | awk 'NR==8'
2436 USER 20 0 1040580 155268 91100 S 6.2 1.0 56:38.94 Xorg
Terminated
I tried:
$ gpu=($(timeout 1s top -d 2 | awk 'NR==8'))
$ mapfile -t gpu < <($(timeout 1s top -d 2 | awk 'NR==8'))
and, departing from the array requisite, even:
$ read -r gpu < <(timeout 1s top -d 2 | awk 'NR==8')
all returned a blank for either ${gpu[#]} (first two) or $gpu (last).
Edit:
As pointed out by #Cyrus and others gpu=($(top -n 1 -d 2 | awk 'NR==8')) is the obvious solution. However I want to build the cmd dynamically so top -d 2 may be replaced by other cmds such as htop -d 20 or intel_gpu_top -s 1. Only top can limit its maximum number of iterations, so that is not an option in general, and for that reason I resort to timeout 1s to kill the process in all shown attempts...
End edit
Using a shell other than Bash is not an option. Why did the above attempts fail and how can I achieve that ?
Why did the above attempts fail
Because redirection to pipe does not have terminal capabilities, top process receives SIGTTOU signal when it tries to write the terminal and take the terminal "back" from the shell. The signal causes top to terminate.
how can I achieve that ?
Use top -n 1. Generally, use the tool specific options to disable using terminal utilities by that tool.
However I want to build the cmd dynamically so top -d 2 may be replaced by other cmds such as htop -d 20 or intel_gpu_top -s 1
Write your own terminal emulation and extract the first line from the buffer of the first stuff the command displays. See GNU screen and tmux source code for inspiration.
I dont think you need the timeout there if its intended to quit top. You can instead use the -n and -b flags but feel free to add it if you need it
#!/bin/bash
arr=()
arr[0]=$(top -n 1 -b -d 2 | awk 'NR==8')
arr[1]=random-value
arr[2]=$(top -n 1 -b -d 2 |awk 'NR==8')
echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
output:
1 root 20 0 99868 10412 7980 S 0.0 0.5 0:00.99 systemd
random-value
1 root 20 0 99868 10412 7980 S 0.0 0.5 0:00.99 systemd
from top man page:
-b :Batch-mode operation
Starts top in Batch mode, which could be useful for sending output from top to other programs or to a
file. In this mode, top will not accept input and runs until the iterations limit you've set with the
`-n' command-line option or until killed.
-n :Number-of-iterations limit as: -n number
Specifies the maximum number of iterations, or frames, top should produce before ending.
-d :Delay-time interval as: -d ss.t (secs.tenths)
Specifies the delay between screen updates, and overrides the corresponding value in one's personal
configuration file or the startup default. Later this can be changed with the `d' or `s' interactive
commands.

Commands Working In Terminal, But Not In Bash Script

I'm sysadmin for couple of webservers deployed with cpanel hosting panel. I'm trying to finish up with a backup script. There are two commands bundled with Cpanel, that will be used in this script. These commands are;
1. whmapi1 modifyacct user=USERNAME BACKUP=[01]
This Command has booleans to set, what it does is either enable or
disable backup for a specific user.
2. /usr/local/cpanel/bin/backup --force
Once backup is enabled for a user/users, then this command starts the
backup process on the server.
So here is my script logic & the script.
#!/bin/bash
Arrays
L=($( comm -23 <(du -h --max-depth=1 /home 2>/dev/null | grep G | awk -F"/" '{print $NF}' | sort | egrep -vw '(home|virtfs)') <(ls -al /var/cpanel/suspended/ | grep -v 'lock' | sort) ))
Above Array contains all the account whose home directories have
exceeded 1GB limit.
S=($(comm -23 <(du -h --max-depth=1 /home 2>/dev/null | egrep -v '(!G|.cp|cP|clamav)' | awk -F"/" '{print $NF}' | sort | egrep -vw '(home|virtfs)') <(ls -al /var/cpanel/suspended/ | grep -v 'lock' | sort) ))
Above Array contains all the account whose home directories are less
than 1GB limit.
whmapi1 modifyacct user=${L[#]} BACKUP=0 && whmapi1 modifyacct user=${S[#]} BACKUP=0
Above command disables backup for all users for start, to start from
scracth.
whmapi1 modifyacct user=${S[#]} BACKUP=1
T
his command enables backup for all accounts whose home dirs are less
than 1 GB
/usr/local/cpanel/bin/backup --force
This command starts backup process for all enabled users.
The logic is, that I want to create backup of small accounts first, and then when it's finished, I'll run it for larger accounts.
PROBLEM: all commands execute successfully when run directly in terminal, but it doesn't when run via a script. Problem occurs at account enabling & disabling.
It either disables all or enables all, and not the partial accounts, as intended by the logic of the script.
Can anyone point out, where & what I'm missing?
Thanks in advance !!
${l[#]} exands to user1 user2 user3 ..., so user=${L[#]} expands to user=user1 user2 user3 ..., if you want to fun foreach user, you need to loop over users.
du_buff=$(du -h --max-depth=1 /home 2>/dev/null)
lock_buff=$(ls -al /var/cpanel/suspended/ | grep -v 'lock' | sort)
L=($(comm -23 <(echo "$du_buff" | grep G | awk -F"/" '{print $NF}' | sort | egrep -vw '(home|virtfs)') <(echo "$lock_buff") ))
S=($(comm -23 <(echo "$du_buff" | egrep -v '(!G|.cp|cP|clamav)' | awk -F"/" '{print $NF}' | sort | egrep -vw '(home|virtfs)') <(echo "$lock_buff") ))
# for every user in L and S
for user in "${L[#]}" "${S[#]}"; do
whmapi1 modifyacct user=$user BACKUP=0
done
# for every user in S
for user in "${S[#]}"; do
whmapi1 modifyacct user=$user BACKUP=1
done
/usr/local/cpanel/bin/backup --force

Find tmux session that a PID belongs to

I am using htop so see what processes are taking up a lot of memory so I can kill them. I have a lot of tmux sessions and lots of similar processes. How can I check which tmux pane a PID is in so I can be sure I am killing stuff I want to kill?
Given that PID in the below line is the target pid number:
$ tmux list-panes -a -F "#{pane_pid} #{pane_id}" | grep ^PID
The above will identify the pane where the PID is running. The output will be two strings. The first number should be the same as PID and the second one (with a percent sign) is "tmux pane id". Example output:
2345 %30
Now, you can use "tmux pane id" to kill the pane without "manually" searching for it:
$ tmux kill-pane -t %30
To answer your question completely, in order to find *tmux session* that a PID belongs to, this command can be used:
$ tmux list-panes -a -F "#{pane_pid} #{session_name}" | grep ^PID
# example output: 2345 development
Here's another possibly useful "line":
$ tmux list-panes -a -F "#{pane_pid} #{session_name}:#{window_index}:#{pane_index}" | grep ^PID
# example output: 2345 development:2:0
The descriptions for all of the interpolation strings (example #{pane_pid}) can be looked up in tmux man page in the FORMATS section.
The answers above give you the pids of the shells running in the panes, you'll be out of luck if you want to find something running in the shells.
try:
https://gist.github.com/nkh/0dfa8bf165a53832a4b5b17ee0d7ab12
This scrip gives you all the pids as well as the files the processes have opened. I never know in which session, window, pane, attached or not, I have a file open, this helps.
I haven't tried it on another machine, tell me if you encounter any problem.
lsof needs to be installed.
if you just want pids, pstree is useful, you can modity the script to use it (it's already there commented)
The following script displays the tree of processes in each window (or pane). It takes list of PIDs as one parameter (one PID per line). Specified processes are underlined. It automatically pipes to less unless is a part of some other pipe. Example:
$ ./tmux-processes.sh "$(pgrep ruby)"
-- session-name-1 window-index-1 window-name-1
7184 7170 bash bash --rcfile /dev/fd/63 -i
7204 7184 vim vim ...
-- session-name-2 window-index-2 window-name-2
7186 7170 bash bash --rcfile /dev/fd/63 -i
10771 7186 bash bash ./manage.sh runserver
10775 10771 django-admi /srv/www/s1/env/bin/python /srv/www/s1/env/bin/...
5761 10775 python /srv/www/s1/env/bin/python /srv/www/s1/env/bin/...
...
tmux-processes.sh:
#!/usr/bin/env bash
set -eu
pids=$1
my_pid=$$
subtree_pids() {
local pid=$1 level=${2:-0}
if [ "$pid" = "$my_pid" ]; then
return
fi
echo "$pid"
ps --ppid "$pid" -o pid= | while read -r pid; do
subtree_pids "$pid" $((level + 1))
done
}
# server_pid=$(tmux display-message -p '#{pid}')
underline=$(tput smul)
# reset=$(tput sgr0) # produces extra symbols in less (^O), TERM=screen-256color (under tmux)
reset=$(echo -e '\033[m')
re=$(echo "$pids" | paste -sd'|')
tmux list-panes -aF '#{session_name} #{window_index} #{window_name} #{pane_pid}' \
| while read -r session_name window_index window_name pane_pid; do
echo "-- $session_name $window_index $window_name"
ps -p "$(subtree_pids "$pane_pid" | paste -sd,)" -Ho pid=,ppid=,comm=,args= \
| sed -E 's/^/ /' \
| awk \
-v re="$re" -v underline="$underline" -v reset="$reset" '
$1 ~ re {print underline $0 reset}
$1 !~ re {print $0}
'
done | {
[ -t 1 ] && less -S || cat
}
Details regarding listing tmux processes you can find here.
To underline lines I use ANSI escape sequences. To show the idea separately, here's a script that displays list of processes and underlines some of them (having PIDs passed as an argument):
#!/usr/bin/env bash
set -eu
pids=$1
bold=$(tput bold)
# reset=$(tput sgr0) # produces extra symbols in less (^O), TERM=xterm-256color
reset=$(echo -e '\033[m')
underline=$(tput smul)
re=$(echo "$pids" | paste -sd'|')
ps -eHo pid,ppid,comm,args | awk \
-v re="$re" -v bold="$bold" -v reset="$reset" -v underline="$underline" '
$1 ~ re {print underline $0 reset}
$1 !~ re {print $0}
'
Usage:
$ ./ps.sh "$(pgrep ruby)"
Details regarding less and $(tput sgr0) can be found here.

Request user input based on an unknown number of mac addresses in bash

I need to write a quick bash script that asks the user which mac address should be used as a variable in the rest of the script. I can get the mac addresses using the following
ip addr | grep ether | cut -d ' ' -f6
After this, I'm not sure how to make an array of the given data, since this will depend on each machine, and then ask the user which one to choose based on an integer as input.
You can use select
select mac in `ip addr | grep ether | cut -d ' ' -f6`
do
if [[ -n $mac ]]
then
# put your command here
echo $mac
break
fi
done

Pass stdin into Unix host or dig command

Let's say I have a list of IPs coming into a log that I'm tailing:
1.1.1.1
1.1.1.2
1.1.1.3
I'd like to easily resolve them to host names. I'd like to be able to
tail -f access.log | host -
Which fails as host doesn't understand input from stdin in this way. What's the easiest way to do with without having to write a static file or fallback to perl/python/etc.?
Use xargs -l:
tail -f access.log | xargs -l host
You could also use the read builtin:
tail -f access.log | while read line; do host $line; done
In the commands below, replace cat with tail -f, etc. if needed.
Using host:
$ cat my_ips | xargs -i host {}
1.1.1.1.in-addr.arpa domain name pointer myhost1.mydomain.com.
1.1.1.2.in-addr.arpa domain name pointer myhost2.mydomain.com.
Using dig:
$ cat my_ips | xargs -i dig -x {} +short
myhost1.mydomain.com.
myhost2.mydomain.com.
Note that the -i option to xargs implies the -L 1 option.
To first get the IPs of one's host, see this answer.
In bash You can do:
stdout | (dig -f <(cat))
Example program:
(
cat <<EOF
asdf.com
ibm.com
microsoft.com
nonexisting.domain
EOF
) | (dig -f <(cat))
This way You only invoke 'dig' once.

Resources