如何通过GUI对话框提示用户通过命令行选择文件/目录路径?


16

假设我有一个这样的脚本:

(该示例描述了rysnc用例)

#!/bin/bash
echo -n "Enter Source Directory:"
read srcdir
echo -n "Enter Destination Directory:"
read dstdir
rsync -av --delete "$srcdir" "$dstdir"

这里的想法是提示用户输入“ Source”和“ Destination”目录以供rsync使用。照原样,用户将必须通过命令行手动输入 /path/to/directory/

相反,我想提示用户通过GUI界面输入路径。

像这样: 筛


我可以使用哪些命令通过GUI选择窗口提示用户,该窗口将文件路径返回到命令行?



4
请记住添加有关GUI窗口使用的警告。不必要的窗口弹出会激怒高级用户。
unperson325680 2014年

5
为什么,哦,为什么您要实现这种烦人的“功能”?请记住,如果我们在命令行输入目录,则可以使用制表符补全,而无需等待某些gui加载。为什么有人要在完美的shell脚本中添加GUI,这超出了我的范围。
terdon

1
由于我们在混合范例,为什么不让用户通过Web应用程序输入路径?
图兰斯·科尔多瓦2014年

4
@terdon因为如果我们直接运行脚本而不是在终端中运行,那么我想提供GUI窗口。
潘迪

Answers:


34

您可以将其用于文件:

zenity --file-selection

这对于文件夹:

zenity --file-selection --directory

要使用,请运行:

zenity --help-general
zenity --help-file-selection

通常,它与当前主题匹配(无论如何对于GTK窗口管理器而言),在我的机器上具有Zukitwo 3.8的修改版,它看起来像这样:

一种使用它的方式是这样的:

echo "you selected $(zenity --file-selection)"

这将导致you selected /path/to/file

您还可以使用选项设置适当的标题,以及该目录的起始位置-使用rsync用例,例如:

zenity --file-selection --directory --title="Choose rsync source directory" --filename=$HOME/Desktop/

对于文件,您还可以指定要选择的文件类型-例如:

zenity --file-selection --file-filter='PDF files (pdf) | *.pdf' --title="Select a PDF file"

注意:您也可以使用YAD,它是Zenity的一个分支,具有很多功能。

sudo add-apt-repository ppa:webupd8team/y-ppa-manager
sudo apt-get update
sudo apt-get install yad

资源

在大多数情况下,您可以以相同的方式使用它-对于文件浏览器:

yad --file-selection

以及帮助页面:

yad --help-all

尽管当时(版本26左右),它尚未进行更新以匹配新的GTK 3.14+界面(zenity已拥有)-它具有更多功能,但检查兼容性(基于文档,它应适用于GTK +> = 2.16。 0


2
Yad是Zenity的一个显着增强的分支,并且自Zenity项目进入休眠状态以来已在很大程度上取代了Yad。我看到Zenity现在已经在Gnome.org(仅限于Gnome3?)上重新开发,但是我看不到下载它的方法。
DocSalvager 2014年

@DocSalvage-该页面相当古老-它说下一个发行版'3.2'-我在现在相当老的Fedora 19系统上安装了3.8版本(使用Gnome 3.8-为每个版本的Gnome Shell更新了很多gnome(因此它可能已更新为3.10 + 3.12))。最后,它还处理2005-2009年的错误报告。你可以从Ubuntu软件库的最新稳定版本(3.8再次) - packages.ubuntu.com/trusty/zenity。您还应该可以在这里找到Yad的编译版本。
2014年

Yad看起来相当不错-它比zenity还多:)
Wilf

1
@Wilf是的,yad是类固醇的Zenity。一旦掌握了它的灵活性,它就会动摇。我是a依者。我补充说(抱歉,无法抗拒),顺便说一句。
Scooby-

@ Scooby-2酷添加了安装说明来回答(因此将来的用户不必做评论)
Wilf

19

仅作记录,您可以使用dialog基于文本的用户界面(TUI)解决方案。

句法:

dialog --title "text" --fselect /path/to/dir height width

例:

FILE=$(dialog --stdout --title "Please choose a file" --fselect $HOME/ 14 48)
echo "${FILE} file chosen."

输出将是这样的:

例

正如@Wilf指出的那样,您可以使用$LINES$COLUMNS变量使它填充终端:

$(dialog --stdout --title "Please choose a file" --fselect $HOME/ $(expr $LINES - 15) $(expr $COLUMNS - 10))

1
尽管它是正确的替代解决方案,但它没有提供所提到的GUI窗口
潘迪2014年

2
我知道,但是其他人可能会觉得有用。我发布了屏幕截图以避免任何混乱。
kraxor 2014年

7
而且,公平地说,它有资格作为GUI IMHO。
kraxor 2014年

3
GUI和TUI(文本UI)之间常用的线是“原子”的大小:是像素还是字符?
unperson325680

3
好的答案-某些终端的宽度和高度由诸如$LINES和的变量定义$COLUMNS-因此,您$(dialog --stdout --title "Please choose a file" --fselect $HOME/ $(expr $LINES - 15) $(expr $COLUMNS - 10))设法使其填充终端/屏幕窗口。
Wilf 2014年

5

我知道这已经8个月大了,并且OP的问题已经回答。但是,已经提到了yad,但没有提供示例。这是我使用yad的解决方案。

DIR="/home" \
i=0;for location in source destination
do
((i++));selection[$i]=$(yad --center \
--width 350 \
--form \
--title="yad example" \
--text="Select $location directory" \
--field=:LBL "" \
--field=Path:DIR "$DIR" \
--separator='' )
done;\
echo "Command to run is \"rsync -av --delete ${selection[1]} ${selection[2]}\""

它的工作方式是这样的。我们把连日来在for循环中,变量设置$locationsource了第一遍和destination第二。输出放置在该数组selection[]用作变量i的索引中。在开始时将其设置为0,并在每次通过时递增。因此,源另存为${selection[1]},目标另存为 ${selection[2]}

第一行的DIR =“ / home”设置对话框的默认值。可以通过在终端上从终端找到yad命令选项yad --help

yad屏幕截图


2

这是答案的最短(也是最好)的解决方案: Yad就像提供正确的选择一样zenity

yad --file-selection --directory

这将打开目录选择对话框。如果没有其他参数--directory,它将是一个文件选择对话框。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.