Solved

improve Shell script

Posted on 2016-07-24
5
137 Views
Last Modified: 2016-07-31
Hi Guys, I'm trying to improve my Shell script a little.
Basically it's a simple script that uses Zenity to display a form that I can use to RDP to other computers using rdesktop.
What I'd like to achieve is the following... Save previous servers I've visited into a file that Zenity can read from and later on display as a drop down list on the Hostname\IP field (While still accepting manual imput of course)
and I'd like to add a field called Resolution in which I can select from a drop-down list of resolutions in which to run rdesktop.

Original script follows:
#!/bin/bash
ans=`zenity --width=400 --height=200  --forms --title="Remote desktop client (Windows)" --text="Remote desktop computer" --add-entry="Hostname\IP" --add-entry="Username" --add-entry="Domain"  --add-password="Password"`
ip_s=`echo $ans | cut -f1 -d"|"`
user=`echo $ans | cut -f2 -d"|"`
doma=`echo $ans | cut -f3 -d"|"`
pass=`echo $ans | cut -f4 -d"|"`

if [ -z $user ]; then
     user='Administrator'
fi

if [  ! $doma ]; then 
                #echo $user $doma $pass
                rdesktop -g1920x1040 -z -u $user -p $pass $ip_s -0 -5 -K -r clipboard:CLIPBOARD
        else 
            rdesktop -g19201040 -z -d $doma -u $user -p $pass $ip_s -0 -5 -K -r clipboard:CLIPBOARD
fi
if [ $? == "76" ]; then
                zenity --error --text "Unable to connect !!!"

Open in new window

0
Comment
Question by:David Sankovsky
  • 3
  • 2
5 Comments
 
LVL 19

Expert Comment

by:simon3270
ID: 41728485
I've had a look at zenity, and I think you are asking too much of it!  It's a simple, single-purpose-at-a-time dialog system, so it can do a form (as you have) or a list, not both at the same time.  it can't, as far as I can tell, even do two lists.

What you may have to do is ask the questions one by one.  For the resolutions, pass them as separate parameters on the command line, such as
    res=`zenity --list --column="Resolution" 1600x1200 1280x1024 1024x768`
and it will pass back the selected item

For the IP addresses (or host names), do something like

hosts=`cat /path/to/saved/hosts.lst`

 ip_s=`zenity --list --column="Target host" $hosts

(assumes that the hosts don't have any spaces in them - they shouldn't have!)

then add the new Ip to the hosts file if not already there, and sort into order.  

    if ! grep -q "^${ip_s}$" /path/to/saved/hosts.lst; then
      echo $ip_s >> /path/to/saved/hosts.lst
      sort -u /path/to/saved/hosts.lst > /tmp/h && mv -f /tmp/h /path/to/saved/hosts.lst
    fi
0
 
LVL 6

Author Comment

by:David Sankovsky
ID: 41728865
Thanks a lot, that does seem to be a step in the right direction, however, when I use

 ip_s=`zenity --list --column="Target host" $hosts

Open in new window


I run into a problem as the list is till empty.

I need it to be like a combo box, where I can select from a drop down list but also input the IP Address manually
0
 
LVL 6

Author Comment

by:David Sankovsky
ID: 41728946
Please see my Current Version.. I need to somehow allow multibox for the IP / Host.

#!/bin/bash

# Display the Zenity window and read the user responses into $ans.
hosts=`cat /scripts/hosts.lst`
ip_s=`zenity --entry --title "Connection Target" --text "Enter the hostname or IP." "${hosts[@]}"`
ans=`zenity --width=400 --height=200  --forms --title="Remote desktop client (Windows)" --text="Remote desktop computer" --add-entry="Username" --add-entry="Domain"  --add-password="Password"`
res=`zenity --list --column="Resolution" 1920x1040 1440x900 1280x1024 1024x768`


# Read Answers from Zenity Window into the needed parameters.
user=`echo $ans | cut -f1 -d"|"`
doma=`echo $ans | cut -f2 -d"|"`
pass=`echo $ans | cut -f3 -d"|"`

#Check if IP is in list and if not, save it to the list.
if ! grep -q "^${ip_s}$" /scripts/hosts.lst; then
   echo $ip_s >> /scripts/hosts.lst
   sort -u /scripts/hosts.lst > /tmp/h && mv -f /tmp/h /scripts/hosts.lst
fi

# Assume user Administrator if no user specified
if [ -z $user ]; then
     user='Administrator'
fi

#Initiate the rdesktop session based on the recieved Parameters.
if [  ! $doma ]; then 
            # If domain is not specified, do not pass the parameter to rdesktop
            rdesktop -g$res -z -u $user -p $pass $ip_s -0 -5 -K -r clipboard:CLIPBOARD
        else 
        	# If domain is specified, pass the parameter to rdesktop
            rdesktop -g$res -z -d $doma -u $user -p $pass $ip_s -0 -5 -K -r clipboard:CLIPBOARD
fi

if [ $? == "76" ]; then
                zenity --error --text "Unable to connect !!!"
fi

Open in new window

0
 
LVL 19

Accepted Solution

by:
simon3270 earned 500 total points
ID: 41729445
I don't think zenity does dropdowns, it just displays a list with one entry per line.  One thing which might make it clearer is to add a radio button before each host, so it is more obvious that you are selecting one.

There is an "--editable" flag which is supposed to make this sort of list update-able in the GUI, but that doesn't seem to work - it pops up a box you can type in, but as soon as you press enter is disappears and that text is lost.

One way to do it is to add a "NewEntry" host as an option - if you click that, you then pop up a standard text input form to get the new host name.  Another thing I'd do is add a flag to suppress the column header - just make sure that the "--text" text says what the entries are.

The structure of the radio button list is:
     zenity --list --radiolist --text="Select host" --hide-header --column="Pick" --column="Hosts" TRUE host1 FALSE host2 FALSE thirdhost FALSE 10.2.3.4
This displays
   Select host
@  host1
O  host2
O  thirdhost
O 10.2.3.4

Open in new window

with the standard Cancel/OK buttons.  The "@" is showing the filled-in radio button (the entry with "TRUE" before it on the command line) - if you click another entry, that line's "O" will be filled in, and the one on the first line will be emptied.  When you click OK or press Enter, the selected item will be sent to stdout.  Note that the "Pick" and "Hosts" headers are not displayed.

The full code for your one might be:
hosts="TRUE NewEntry `sed 's/^/FALSE /' /scripts/hosts`"
ip_s=`zenity --list --radiolist --title "Connection Target" --text "Enter the hostname or IP." \
--hide-header --column="Pick" --column="Hosts" $hosts`
if [ "$ip_s" = "NewEntry" ]; then
  # Standard zenity form for inputting the new hostname
  # then the code to add the new name to the /scripts/hosts file and doing the sort and mv
fi
# Now carry on twith your "ans=" line

Open in new window

The first line puts "TRUE NewEntry" as the start of the list (so that the "NewEntry" item is selected by default), then adds "FALSE" in front of each host name so those entries aren't marked as selected.  Don't have a space in "NewEntry" or it will mess things up!  The second line is the list form, which will pop up with NewEntry as the selected entry - note that $hosts doesn't have quotes round it - we want the shell to split it into separate words.

BTW, in the full code you gave, you have "hosts=`cat /scripts/hosts` but then use "${hosts[@]}" on the command line - $hosts isn't an array, it's just a string with space-separated items, so just use $hosts with no quotes.  I think that the reason the list dialog was empty was that the hosts file is initially empty - once you have a host in the file, you wouldn't have had the empty list.  In this updated version above, there is always at least one entry in the list (the NewEntry one), so you won't have an empty list displayed.
0
 
LVL 6

Author Closing Comment

by:David Sankovsky
ID: 41736233
Got me going in the right direction. Thanks
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
Utilizing an array to gracefully append to a list of EmailAddresses
Connecting to an Amazon Linux EC2 Instance from Windows Using PuTTY.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now