2

I have an extremely simple script that currently executes a command on a file located in the same folder: command ./file_in_folder option output. It would be better if script asks user which file they want.

Can a simple script ask the OS's default GUI file manager to open and pass selected file back to script?

Fake Code:

  • User double click executable script
  • GUI file manager pops up
  • User selects <FILE>
  • Script executes command <FILE> option output

If no, what is recommended way to pass <FILE> to script that will execute command <FILE> option output?

  • 2
    I'm not sure if what you want is possible, so I'm not making a full answer; but for a simple script, you're probably better off using a text-based dialog creator, like Zenity. For a quick example, see askubuntu.com/questions/244836/… – chaskes Jan 31 '15 at 1:47
  • Alternately, you can always pass the name through STDIN and save it as a variable for later use. – heemayl Jan 31 '15 at 1:49
  • 1
    I second @chaskes, zenity is the tool for this. See the GNOME docs on file selection: help.gnome.org/users/zenity/stable/file-selection.html.en – muru Jan 31 '15 at 2:04
  • 1
    @muru Nice link to the docs. I haven't used Zenity for a while and forgot about some of the built-ins, like file-selector. You ought to make an answer. – chaskes Jan 31 '15 at 2:12
  • Or read a list of files (from ls maybe), display the results and ask for a "pick file number 1 through n", using zenity or just the terminal? – Xen2050 Jan 31 '15 at 4:03
4

Zenity can be used to make a GUI file picker, using the --file-selection option. For a single file, this is sufficient:

#! /bin/bash

file="$(zenity --title "Pick a file" --file-selection)"
do something with "$file"

enter image description here

Where it gets tricky is handling multiple files. There are only two characters not allowed in filenames: the ASCII NULL and /. /, of course, appears in paths. Therefore the only character you can safely pick to separate two filenames is NUL. You can't use NUL since the character has to be passed as a command line parameter.

You have two options:

  • Pick one file at a time using repeated selection dialogs.
  • Verify that each path returned by zenity is an absolute path and the file exists.

Something like:

#! /bin/bash

OLDIFS="$IFS"
IFS='-'
FILES=($(zenity --file-selection --multiple --separator='-' --title "Pick a file"))
IFS="$OLDIFS"

for file in "${FILES[@]}"
do
    if [[ $file == /* && -f $file ]]
    then
        echo $file
    fi
done

Of course, even this does not save us from a filename like /foo/bar-/etc/passwd. So be careful if your script runs with higher privileges than the user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.