I was adding some new features on PiParted recently and needed a simple file browser for my PiParted script. I couldn’t find anything online for this sort of thing, so I built my own file browser of sorts.
Using whiptail and the output of ls (which isn’t recommended but I’ll get around to posting an updated version of this script sometime), I managed to get a simple file browser to allow a user to pick a file.
I’ll paste bits and pieces of the code to explain it, and then paste the whole function at the end of this post.
This starts off with an if statement to check to see whether a path has been passed to the script. If it hasn’t it will start the listing off at /
, Otherwise it will start at the path it had been passed.
function Filebrowser() {
if [ -z $1 ]; then
imgpath=$(ls -lhp / | awk -F ' ' ' { print $9 " " $5 } ')
else
imgpath=$(ls -lhp "/$1" | awk -F ' ' ' { print $9 " " $5 } ')
fi
Next, still checking to see whether it was passed a path, it will show a back button if it was passed a path.
if [ -z $1 ]; then
pathselect=$(whiptail --menu "Select Image File" 40 50 30 --cancel-button Cancel --ok-button Select $imgpath 3>&1 1>&2 2>&3)
else
pathselect=$(whiptail --menu "Select Image File" 40 50 30 --cancel-button Cancel --ok-button Select ../ BACK $imgpath 3>&1 1>&2 2>&3)
fi
Next, it checks the return value to make sure it was 0 to signify the user didn’t press cancel
After that, it checks the path the user selected to see if it was a directory, if it is then it re-runs the function and passes a path
Otherwise it will determine whether the file selected is the file type that is required, and if it is show that it is about to perform an action. If it’s not the type required, present an error to the user.
RET=$?
if [ $RET -eq 0 ]; then
if [[ -d "/$1$pathselect" ]]; then
Filebrowser "/$1$pathselect"
elif [[ -f "/$1$pathselect" ]]; then
fileout=`file "$1$pathselect"
filename=`readlink -m $1$pathselect`
if [[ $fileout =~ x86\ boot\ sector$ ]]; then
whiptail --yesno --title "! WARNING !" "About to try and automatically resize $filename. Are you sure ?" 10 50
### This bit of the code would be what you want to do after the user has selected the right type of file.
if [ $? -ne 0 ]; then
Filebrowser
fi
else
whiptail --msgbox --title "! ERROR ! ERROR ! ERROR ! " "Selected file is not an image file." 8 44
Filebrowser
fi
And lastly, check to make sure the path that was passed to the script is valid. At the moment, I don’t imagine this script would handle spaces well so you may see this error message when processing directories with spaces in their names.
else
echo pathselect $1$pathselect
whiptail --title "! ERROR !" --msgbox "Error setting path to image file." 8 44
unset base
unset imgpath
Filebrowser
fi
exit 0
And, as promised, the whole code in one big block
Filebrowser() {
if [ -z $1 ]; then
imgpath=$(ls -lhp / | awk -F ' ' ' { print $9 " " $5 } ')
else
imgpath=$(ls -lhp "/$1" | awk -F ' ' ' { print $9 " " $5 } ')
fi
if [ -z $1 ]; then
pathselect=$(whiptail --menu "Select Image File" 40 50 30 --cancel-button Cancel --ok-button Select $imgpath 3>&1 1>&2 2>&3)
else
pathselect=$(whiptail --menu "Select Image File" 40 50 30 --cancel-button Cancel --ok-button Select ../ BACK $imgpath 3>&1 1>&2 2>&3)
fi
RET=$?
if [ $RET -eq 1 ]; then
## This is the section where you control what happens when the user hits Cancel
AdvancedMenu
exit 0
elif [ $RET -eq 0 ]; then
if [[ -d "/$1$pathselect" ]]; then
Filebrowser "/$1$pathselect"
elif [[ -f "/$1$pathselect" ]]; then
## Do your thing here, this is just a stub of the code I had to do what I wanted the script to do.
fileout=`file "$1$pathselect"`
filename=`readlink -m $1$pathselect`
if [[ $fileout =~ x86\ boot\ sector$ ]]; then
whiptail --yesno --title "! WARNING !" "About to try and automatically resize $filename. Are you sure ?" 10 50
if [ $? -ne 0 ]; then
Filebrowser
fi
else
whiptail --msgbox --title "! ERROR ! ERROR ! ERROR ! " "Selected file is not an image file." 8 44
Filebrowser
fi
else
echo pathselect $1$pathselect
whiptail --title "! ERROR !" --msgbox "Error setting path to image file." 8 44
unset base
unset imgpath
Filebrowser
fi
exit 0
fi
}
This doesn’t seem to handle symbolic links and provides a back button on root, otherwise it’s perfect!
Thanks for the feedback. It was a really hacky solution that I needed for something, but thought it’d be useful to save haha. If you can suggest any improvements, I’ll update this post.
This was extremely helpful, really nice whiptail script