Map key sequence of more than two keys - keyboard

I have created and script that uses xdotool to open new tabs in specific firefox containers. I need to map three keys, for instance ctrl+y+p to open a personal container, ctrl+y+b to open the banking container and so on. I cannot find a tool that lets you map more than two keys.
Is there something like what I have described?
Thanks a lot.
Edit: For anyone looking for an answer, I found a way. I use i3 so I just added a mode triggered by pressing the first two keys and then mapped the "b" to the command + escape (to exit the mode).

Install xdotool if you haven't already done so, for example:
sudo apt-get install xdotool
As per your example (CTRL+y+p), execute:
DISPLAY=:0 xdotool keydown ctrl keydown y keydown p
Which presses the three keys but does not release them after. An alternative way:
DISPLAY=:0 xdotool key ctrl+y+p
:0 is a typical value for the display, but in my Raspberry Pi, for example, it needed to be DISPLAY=:10. If you are still having trouble with the display variable and get a message like this:
xdotool can't open display (null)
then you could obtain the display value with:
ps -u $(id -u) -o pid= | \
while read pid; do
cat /proc/$pid/environ 2>/dev/null | tr '\0' '\n' | grep '^DISPLAY=:'
done | grep -o ':[0-9]*' | sort -u
Another alternative way to obtain DISPLAY values (it will be the number after the ':' )
xauth list
This works in raspbian too:
w -hs | awk '{print $3}' | sort -u | grep -v -
Good luck

Related

Write mouse coordinates and mouse clicks with timestamps to file?

I'm trying to create a bash script that records the location of the mouse every 5 milliseconds. I also want to record the timestamps and locations of mouse-clicks.
Recording the mouse location has been easy with xdotool getmouselocation. I've been able to record mouse clicks using some of the suggestions here: https://unix.stackexchange.com/questions/106736/detect-if-mouse-button-is-pressed-then-invoke-a-script-or-command
However, I've not been able to combine the two.
Is there any way to accomplish this? Thank you in advance!
In accepted answer of https://unix.stackexchange.com/questions/106736/detect-if-mouse-button-is-pressed-then-invoke-a-script-or-command have an example to get mouse status change. With little modification you get print the mouse location upon mouse button down.
#Gem Taylor mentioned using script language for this is not an optional way.
During test run, I experienced cases when clicks are not get captured.
#!/bin/bash
MOUSE_ID=$(xinput --list | grep -i -m 1 'mouse' | grep -o 'id=[0-9]\+' | grep -o '[0-9]\+')
STATE1=$(xinput --query-state $MOUSE_ID | grep 'button\['"."'\]=down' | sort)
while true; do
sleep 0.005
STATE2=$(xinput --query-state $MOUSE_ID | grep 'button\['"."'\]=down' | sort)
CLICK=$(comm -13 <(echo "$STATE1") <(echo "$STATE2"))
if [[ -n $CLICK ]]; then
echo "$CLICK"
xinput --query-state $MOUSE_ID | grep 'valuator\['
fi
STATE1=$STATE2
done

Count the minimized windows on Linux with bash

I'm trying to build a script that checks that windows under XFCE are minimized before displaying a window I've chosen (it's a part from a bigger project)
I tried to recover the count of the open windows with wmctrl
but these are not the minimized windows :
CURRWORKSPACE=$(wmctrl -d | grep '*' | cut -d ' ' -f1)
OPENWINDOWS=$(wmctrl -l | cut -d ' ' -f3 | grep $CURRWORKSPACE | wc -l)
I also try with xdotool, but without success :(
I was wondering if you knew of any way to get this information.
I'm on XFCE, but another way with any tool would be great
Many thanks !
Given a window and its id as listed by wmctrl you can use the following function to determine whether that window is minimized. Note that minimized windows are called iconic in X.
# usage: isMinimized <windowId>
# returns status 0 if and only if window with given id is minimized
isMinimized() {
xprop -id "$1" | grep -Fq 'window state: Iconic'
}
In order to count open windows you can loop over the list of window ids.
openWindows() {
count=0
for id in $(wmctrl -l | cut -f1 -d' '); do
isMinimized "$id" || ((count++))
done
echo $count
}
At least on my desktop environment (Cinnamon) some "windows" were always open. These windows are for instance the Desktop. I adjusted the function by filtering out these windows before looping over them. Since they were sticky and I normally don't use sticky windows I just neglected all sticky windows: $(wmctrl -l | grep -vE '^0x\w* -1' | cut -f1 -d' ').
You can adjust the filtering to your needs. In this case all open and non-sticky windows on all workspaces/desktops are counted.

Show not logged users processes linux bash script

I am doing a bash script and i am essaying to show not logged users processes,which are typically daemon processes, for this,in the exercise, they recommend me:
To process the command line, we will use the cut command, which allows
selecting the different columns of the list through a filter.
I used:
ps -A | grep -v w
ps -A | grep -v who
ps -A | grep -v $USER
but trying all these options all the processes of all users are printed in the output file, and I only want the processes of users who are not logged.
I appreciate your help
Thank you.
grep -v w will remove lines matching the regular expression w (which is simply anything which contains the string w). To run the command w you have to say so; but as hinted in the instructions, you will also need to use cut to post-process the output.
So as not to give the answer away completely, here's rough pseudocode.
w | cut something >tempfile
ps -A | grep -Fvf tempfile
It would be nice if you could pass the post-processed results of w in a pipe, but standard input is already tied to ps -A. If you have a shell which supports process substitution, you can use that.
ps -A | grep -Fvf <(w | cut something)
Unfortunately, the output from w is not properly machine-readable -- you will properly want to cut out the header line(s), too. (On my machine, there are two header lines. Yours might differ.) You'll probably learn a bit of Awk later on in the course, but until then, maybe something like
ps -A | grep -Fvf <(w | tail -n +3 | cut something)
This still doesn't completely handle all possible situations. What if someone's account name is grep?

How can I return grep results one line at a time in order to use the parsed data in another script?

I have a script that I use at work that I'd like to expand on a bit. The script I'm currently using takes an IP address as an arg and pushes a zip file to a specific directory on that device. The device is an Android device, and the specific directory I push to is used to trigger a device recovery using the new data that was pushed.
I'm looking to try to find a way to scan the network, identify all android devices attached, then push the new firmwares to each of them. Since the push part is already easily accomplished, what I need it to find a way to scan and identify the IP's for each attached devices.
I've come up with:
nmap -sL 10.111.1.0/24 | grep android | grep -oE '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}'
which will bounce through the network, find anything with "android" in the line, then parse out and return the IP address of those lines. The problem is, I don't know how to take the IP addresses one at a time and feed them to a script from here. Any ideas?
You can use a for loop and a subshell anytime you have this pattern where you want to act on the result of a pipeline:
for ip in $( nmap -sL 10.111.1.0/24 | grep android | grep -oE '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}' ); do
echo "W00t! I found this ${ip}"
/path/to/script "${ip}"
done
I would use a while loop and parse whatever you get from the grep with a set.
(nmap -sL 10.111.1.0/24 | grep android | grep -oE '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}' | \
while read -a device; do
echo ${device[0]}
echo ${device[1]}
...
/path/to/script ${device[2]} #the number that represents the ip address (I don t know wich one it will be depends what your grep gives)
done)
Now you can get the IP address and push it in the script
Read it into an array:
read -a devices < <(nmap -sL 10.111.1.0/24 | grep android | grep -oE '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}')
Then send it to the script:
/path/to/script "${devices[#]}"

Manipulate window size in linux via compiled code?

I wrote a couple of scripts to maximize a window to half the size of the screen (to make it easy to place windows side-by-side) using xrandr, grep, and wmctrl as follows:
#!/bin/bash
w=`xrandr 2> /dev/null | grep '*' | grep -Po '\d+(?=x)'`
h=`xrandr 2> /dev/null | grep '*' | grep -Po '(?<=x)\d+'`
wmctrl -r :ACTIVE: -b remove,maximized_horz,maximized,vert
wmctrl -r :ACTIVE: -e 0,0,0,$((w / 2)),$h
Is there a way to do this more natively? The script works well on my desktop, but on my laptop there's a half-second lag that is kind of annoying.
test code
# w_h="$(print -- "1280x1024 0.0*" | awk '/.*\*$/{sub(/ .*$/, "");sub("x"," ");$1=$1/2 ;print}')"
# w="${w_h% *}" ; h="${w_h#* }"
actual code
# awk matches only line ending with '*', remove everything from last space to EOL, replace X with " "
# w_H looks like "640 1040", below splits on space char populating correct var
w_h="$(xrandr | awk '/\*/{sub(/[0-9\.*\+]*$/, ""); sub("x", " "); $1=$1/2; print}')"
w="${w_h% *}" ; h="${w_h#* }"
wmctrl -r :ACTIVE: -b remove,maximized_horz,maximized,vert
wmctrl -r :ACTIVE: -e 0,0,0,${w},${h}
Note that I have done the div on W inside awk. Also, backticks are deprecated in posix shells. Make your life easier and use $() for command substituton ;-)
I hope this helps.

Resources