问题
Hi I'm kinda new to bash scripting and not very technical when it comes to writing my own scripts, I have a script that works perfectly in a terminal. I wanted to use zenity to make things nice and simple and straight forward (but also as a little learning project).
The script generates random passwords and with zenity is quite a good little tool.
I have run into a problem though, the script runs well as a GUI but when I wanted to introduce a way for the user to choose the length of the password it fails to produce the password. The code to let the user input their desired number (length of password) :
number=32
zenity --entry --text="Please enter a number (no limitations!) :" --entry-text="$number"
read newnumber
[ -n "$newnumber" ] && number=$newnumber
Which, if run in a terminal displays the number entered in the terminal but not in a zenity box. I cannot use the variable...:
number=$newnumber
...later in the script as desired like so, I changed a variable from :
LENGTH="32"
To :
LENGTH="$newnumber"
The script runs normally (except not producing a password) as a GUI, but in the terminal I get (if the user entered the number 25) :
25
/home/server/Desktop/passwd32gen: line 22: [: : integer expression expected
So it's the fact I've used $newnumber
as the value in the LENGTH=
variable that has broken the generating part of the script. I have tried various different ways to solve this on my own but know too much, I would assume it will be quite a simple missing piece of syntax (or maybe I just hope so).
Now I'm at my wits end trying to figure it out, I've tried
declare
and
eval
in a number of ways but they just seemed to break the script.
Thankyou in advance to anyone who can help in anyway!
And please keep in mind I'm looking for a way to use zenity to allow a user to choose the length of the password being generated.
The whole script is :
#!/bin/bash
# May need to be invoked with #!/bin/bash2 on older machines.
#
#Random 32 character password generator
#
zenity --info --title="32 Character Password Generator" --text="Hi, so you want to get yourself a new password? You've the perfect little application here, just click OK to generate your new password."
number=32
zenity --entry --text="Please enter a number (no limitations!) :" --entry-text="$number"
read newnumber
[ -n "$newnumber" ] && number=$newnumber
MATRIX="0123456789<?/_+-!@#$%^&*>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
# Password will consist of standard characters.
LENGTH="$newnumber"
#This variable can be changed for password lenth (need to try get zenity to let user choose that number)
while [ "${n:=1}" -le "$LENGTH" ]
# := is "default substitution" operator.
# So, if 'n' has not been initialized, set it to 1.
do
PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
# Very clever, but tricky.
# Starting from the innermost nesting...
# ${#MATRIX} returns length of array MATRIX.
# $RANDOM%${#MATRIX} returns random number between 1
# and [length of MATRIX] - 1.
# ${MATRIX:$(($RANDOM%${#MATRIX})):1}
# returns expansion of MATRIX at random position, by length 1.
# See {var:pos:len} parameter substitution in Chapter 9.
# and the associated examples.
# PASS=... simply pastes this result onto previous PASS (concatenation).
# to let zenity show the password being built one character at a time, uncomment the following line
# zenity --info --text="$PASS"
let n+=1
# Increment 'n' for next pass.
done
zenity --info --title="Your 32 character password" --text="Here is your random 32 character password, you can copy and paste it wherever you wish...
$PASS
The passwords generated by this application are very strong, here are the numbers;
Length: 32 characters
Character Combinations: 96
Calculations Per Second: 4 billion
Possible Combinations: 2 vigintillion
Based on an average Desktop PC making about 4 Billion calculations per second
It would take about 21 quattuordecillion years to crack your password.
As a number that's 21,454,815,022,336,020,000,000,000,000,000,000,000,000,000,000 years!" # you could redirect to a file, to store the password. Use something like $PASS 2> /file/name
exit 0
回答1:
If you REALLY want to be able to display the special characters, you can use zenity --text-info as shown below. It's not as aesthetically pleasing, but it can be done.
Just another 2¢
echo "Here is your random $newnumber character password, you can copy and paste it wherever you wish...
$PASS
The passwords generated by this application are very strong, here are the numbers;
Length: $newnumber characters
Character Combinations: 96
Calculations Per Second: 4 billion
Possible Combinations: 2 vigintillion
Based on an average Desktop PC making about 4 Billion calculations per second
It would take about 21 quattuordecillion years to crack your password.
As a number that's 21,454,815,022,336,020,000,000,000,000,000,000,000,000,000,000 years!" | zenity --text-info --title "Your $newnumber character password" --width 600 --height 500`
Addendum,
After playing with it some more, it appears that zenity doesn't like printing variables with special characters.
This script should work
I made 2 changes.
1 newnumber=`zenity.... This will read the input from zenity.
2 Removed some special characters from the MATRIX
I marked all changes with #CHANGED
Here's the revised script.
#!/bin/bash
# May need to be invoked with #!/bin/bash2 on older machines.
#
#Random 32 character password generator
#
zenity --info --title="32 Character Password Generator" --text="Hi, so you want to get yourself a new password? You've the perfect little application here, just click OK to generate your new password."
number=32
# CHANGED
newnumber=`zenity --entry --text="Please enter a number (no limitations!) :" --entry-text="$number"`
# read newnumber
[ -n "$newnumber" ] && number=$newnumber
#CHANGED Removed offending special characters
MATRIX="0123456789?_+-!$%^>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
# Password will consist of standard characters.
LENGTH="$newnumber"
#This variable can be changed for password lenth
#(need to try get zenity to let user choose that number)
while [ "${n:=1}" -le "$LENGTH" ]
# := is "default substitution" operator.
# So, if 'n' has not been initialized, set it to 1.
do
PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
# Very clever, but tricky.
# Starting from the innermost nesting...
# ${#MATRIX} returns length of array MATRIX.
# $RANDOM%${#MATRIX} returns random number between 1
# and [length of MATRIX] - 1.
# ${MATRIX:$(($RANDOM%${#MATRIX})):1}
# returns expansion of MATRIX at random position, by length 1.
# See {var:pos:len} parameter substitution in Chapter 9.
# and the associated examples.
# PASS=... simply pastes this result onto previous PASS (concatenation).
# to let zenity show the password being built one character at a time, uncomment the following line
# zenity --info --text="$PASS"
let n+=1
# Increment 'n' for next pass.
done
# CHANGED $PASS to '$PASS' below
zenity --info --title="Your 32 character password" --text="Here is your random 32 character password, you can copy and paste it wherever you wish...
$PASS
The passwords generated by this application are very strong, here are the numbers;
Length: 32 characters
Character Combinations: 96
Calculations Per Second: 4 billion
Possible Combinations: 2 vigintillion
Based on an average Desktop PC making about 4 Billion calculations per second
It would take about 21 quattuordecillion years to crack your password.
As a number that's 21,454,815,022,336,020,000,000,000,000,000,000,000,000,000,000 years!" # you could redirect to a file, to store the password. Use something like $PASS 2> /file/name
exit 0
回答2:
A read
command following your zenity command won't read from zenity -- it still reads from stdin as always.
Instead, you probably want:
newnumber=$(zenity --entry \
--text="Please enter a number (no limitations!) :" \
--entry-text="$number")
...no following read
command needed.
That said, if you did want to use read
for some reason, you could still do that:
read -r newnumber < <(zenity --entry \
--text="Please enter a number (no limitations!) :" \
--entry-text="$number")
来源:https://stackoverflow.com/questions/25508386/using-a-variable-as-another-variable-in-a-bash-script