Using a variable as another variable in a bash script?

江枫思渺然 提交于 2019-12-13 05:24:47

问题


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 $newnumberas 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!