I am doing a project which behaves like autologin using xdotool. Below is the bash script command:
if [ "$url" == "https://github.com/login" ]; then
sleep 5
xdotool type $WUSER
xdotool key Tab
xdotool type $DECPASS
xdotool key Return
else
exit 1
fi
There will be a default URL for login page (eg: https://github.com/login), which will run this script below on the browser startup:
automatically type in the username
press tab key
type in the password
click enter
At the moment I use sleep 5 (wait 5 seconds until running the next command) which is a bit hacky because some pages load really fast and others don't.
Question
How to check first if the page is fully loaded before running the command? Maybe it will look something like this, or if there's some other better methods.
if [ "$url" == "https://github.com/login" ]; then
if [ <page is fully loaded> ]; then
xdotool type $WUSER
xdotool key Tab
xdotool type $DECPASS
xdotool key Return
else
<wait until page loads>
fi
else
exit 1
fi
This script's logic tries to find if login was successful, instead of trying other things first. This makes it easy for in bash, because other solutions (in bash) are complicated or undoable.
While all these may be great, they can make it very complicated for you.
Instead you want to make it simple for you.. then try this:
sleep 5;
if [[ <check with xdotool search --name for a window to confirm login> ]];
echo " Window exists, login was successful;
else
echo "Login failed, retring.
<Repeat login>
fi;
For instance, I know when I (sucessfully )login to Github, there is a page titled "Github".
Before login, there is a page "Sign in to Github"
So may be i can check if sign in to github page still exists.
#so you'r script will look like this
#keep trying to login, til successs
while true;
do
sleep 5;
#your code to Log-in
if [[ -z "$(xdotool search --name "Sign in to GitHub")" ]];
then
echo "I reckon login was succesfful.";
break 1;
else
echo "Try again.";
fi;
done;
For the above to work, the Browser window must be open in a separate window or
the Tab should be the visible one.
Related
I'm working on a bash script that will add users in a batch process. This code goes as follows:
#!/bin/bash
# A script that creates users.
echo "This is a script to create new users on this system."
echo "How many users do you want to add?"
read am
echo " "
for i in {0..$am..1}
do
echo "Enter a username below:"
read usern
sudo useradd $usern
sudo passwd $usern
echo " "
echo "User $am '$usern' added."
done
In this case, I wanted to make 4 users. I went through and entered the username "callum3" and set the password as "1234" for ease of login. Once I input everything (correctly, may I add) the terminal window displays the following.
User 4 'callum3' added.
This shows that my for loop isn't actually working, when I can see nothing wrong with it. I have tried using a while loop with no luck there either.
Am I making a rookie mistake here or is there something deeper going on?
Although I suspected it, for a better understanding on what could be wrong with your script I pasted it in shellcheck.net. That the problem is in the line:
for i in {0..$am..1}
Bash doesn't support variables in brace range expansions. That is, you cannot use a variable in an expression like {..}.
Instead, use seq. With seq $var you get a sequence from 1 (default) to $var:
for i in $(seq "$am")
I feel like I'm missing something in that nobody has suggested an arithmetic for loop:
for ((i=0; i<am; i++)); do
…
done
This has the particular benefit in bash of being both readable and not requiring a subshell.
You can use:
for i in `seq 0 $((am-1))`
do
...
done
Sequence will start from 0 and end at $am-1
I want to display the value of a real-time variable in a whiptail interface.
I my incremented variable like that =
#!/bin/bash
i=1
while test $i -ne 51
do
echo "$i"
i=$(($i + 1)) #icremente i
done
how I can display the real-time value in a GUI with whiptail?
The usual way would be to pipe the results to a --gauge option (gauge widget). whiptail's manual page lists that.
whiptail implements a subset of dialog's options; if you were using dialog, one might suggest displaying successive --infobox messages (also part of the subset), but the effect with xterm may not be good -- too much flashing (dialog cancels the switch to xterm's alternate screen which many terminal descriptions use).
Here is a sample using the latter:
#! /bin/sh
: ${PROG=whiptail}
left=10
unit="seconds"
while test $left != 0
do
$PROG --title "INFO BOX" "$#" \
--infobox "Hi, this is $left $unit to read this..." 10 52
left=`expr $left - 1`
test $left = 1 && unit="second"
sleep 1
done
If you were to use that in xterm without disabling the alternate screen switching (e.g., setting the resource *titeInhibit:false) it would not work well, of course.
I am trying to figure out how to not lose focus in a shell script while simultaneously displaying an image. User input may come at any time, but seeing the photo taken, would seem important.
To Clarify, I have no problem outputing an image. display works fine, as does animate, and feh, etc.. what i need is for the shellscript to still process user input, (in this example, "t") while displaying the last image taken, for an undefined amount of time.
I'm writing in bash, in Linux.
Heres an example of what I'm trying:
#!/bin/bash
i=0
capture() {
cd ~/Desktop/ani
streamer -c /dev/video0 -s 800x600 -o outfile$i.jpeg
display outfile$i.jpeg &
let i++
}
while true; do
#clear
read -rsn1 input
if [ "$input" = "t" ]; then
capture
else
exit
fi
done
In the actual script I may continue to take photos, so I want to continue listening for user input. I can imagine a couple ways to do this, but I cannot figure it out.
To continue listening user input. you can do like
while true; do
#clear
read -p "Your input: " input
if [ "$input" == "t" ]; then
capture
fi
done
A rather ugly way to solve this: install the utility wmctrl (in debian/Ubuntu, sudo apt-get install wmctrl). Then, after your display command, add:
sleep 1
wmctrl -i -a "$WINDOWID"
This will sleep for one second (to leave some time to the display command to finish loading—tune this value to whatever feels right to you). Then, wmctrl will use the value of the variable WINDOWID (that is hopefully set by your terminal emulator) as a numeric value (-i) and raise the window and give it focus (-a).
I have this script start.sh
#!/bin/bash
while[1]
do
read -sn3 key
if [$key=="\033[[A"]
then
./test1
else
./test2
fi
done
I want to set up a forever loop check see if F1 key pressed. If pressed execute test1 else test2. I did start.sh & running in background so other programs can run.
I got error
while [1] command not found
syntax error near unexpected token 'do'
[f==\033]: command not found
Also where is this read command located? I type which read, it didn't find it.
Also, if try ./start.sh & it gives totally different behavior. I enter a key and it says that key is not found. I though & just run the script at background
There are several basic syntax problems in your code (consider using shellcheck before posting to clean up these things), but the approach itself is flawed. Hitting "q" and "F1" produces different length inputs.
Here's a script relying on the fact that escape sequences all come in the same read call, which is dirty but effective:
#!/bin/bash
readkey() {
local key settings
settings=$(stty -g) # save terminal settings
stty -icanon -echo min 0 # disable buffering/echo, allow read to poll
dd count=1 > /dev/null 2>&1 # Throw away anything currently in the buffer
stty min 1 # Don't allow read to poll anymore
key=$(dd count=1 2> /dev/null) # do a single read(2) call
stty "$settings" # restore terminal settings
printf "%s" "$key"
}
# Get the F1 key sequence from termcap, fall back on Linux console
# TERM has to be set correctly for this to work.
f1=$(tput kf1) || f1=$'\033[[A'
while true
do
echo "Hit F1 to party, or any other key to continue"
key=$(readkey)
if [[ $key == "$f1" ]]
then
echo "Party!"
else
echo "Continuing..."
fi
done
Should be
while :
or
while true
Try this:
#!/bin/bash
while true
do
read -sn3 key
if [ "$key" = "$(tput kf1)" ]
then
./test1
else
./test2
fi
done
It is more robust to use tput to generate the control sequence, you can see a full list in man terminfo. If tput isn't available, you can use $'\eOP' for most terminal emulators or $'\e[[A' for the Linux console (the $ is necessary with the string to make bash interpret escape sequences).
read is a bash builtin command - try help read.
I have a very small script that needs to be run on debian installer: (via preseeding, pre installation script)
echo -n -e " # Your option [1] [2] [3]: "
read REPLY
if [ "$REPLY" == "1" ]
The script stops here and whatever I press is just displayed onto screen however it is not accepting the enter key. Normally, when you press 1 and press enter, the read should return 1 to $REPLY. But nothing happens. It keeps accepting user input but no further action happens.
Then, I switched to tty2 with ALT+F2 and run the script there, it was fine, it works as expected, when I press; it takes the input. Why tty1 is not accepting enter as usual?
Use debconf for that kind of configuration, it tackles exactly needs like yours.
Adapted example from the manual
Template file (debian/templates):
Template: your_package/select_option
Type: select
Choices: 1, 2, 3
Description: Which option?
Choose one of the options
Script (debian/config):
#!/bin/sh -e
# Source debconf library.
. /usr/share/debconf/confmodule
db_input medium your_package/select_option || true
db_go
# Check their answer.
db_get your_package/select_option
if [ "$RET" = "1" ]; then
# Do stuff
fi
Had the same problem (read not processing my input) with busybox on an embedded Linux.
Took me some time to realize that busybox's read is not CR-tolerant — my terminal program (used miniterm.py) sent CR/LF line ends by default; switching it to LF only solved my problem!
with bash interpreter, try replace read by :
builtin read
with other sh interpreter, specify the variable name :
read REPLY
The following script works fine for me:
#!/bin/sh
echo -n -e " # Your option [1] [2] [3]: "
read
case $REPLY in
1 )
echo "one" ;;
2 )
echo "two" ;;
3 )
echo "three" ;;
*)
echo "invalid" ;;
esac
It prints out one nicely if I choose 1. Any reason why you'd like to stick to if...fi?