Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


improve Shell script

Posted on 2016-07-24
Medium Priority
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:
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

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

Open in new window

Question by:David Sankovsky
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
LVL 20

Expert Comment

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

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

Author Comment

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


# 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

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

#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
        	# 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

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

Open in new window

LVL 20

Accepted Solution

simon3270 earned 2000 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
This displays
   Select host
@  host1
O  host2
O  thirdhost

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
# 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.

Author Closing Comment

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

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Utilizing an array to gracefully append to a list of EmailAddresses
Google Drive is extremely cheap offsite storage, and it's even possible to get extra storage for free for two years.  You can use the free account 15GB, and if you have an Android device..when you install Google Drive for the first time it will give…
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Suggested Courses

636 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