如何在bash或shell脚本中提示用户输入一个名称以创建文件夹?

5

首先,这是我第一次尝试编写shell脚本。我只有HTML和CSS的经验:]

我想要做的是设置一个简单的文件夹结构,并在对话框中提示用户设置根文件夹的名称。我将通过OS X服务或Keyboard Maestro热键触发此shell脚本。

到目前为止,这就是我想出来的:

#!/bin/sh

echo -n "Enter the project name:"
read -e NAME  

mkdir -p ~/Desktop/$NAME
mkdir -p ~/Desktop/$NAME/subfolder1
mkdir -p ~/Desktop/$NAME/subfolder2

显然,出现了一些错误——变量无法传递,并且根文件夹也没有被创建。我还读到应该使用“dialog”来请求输入,但我不会编写能够正常工作的代码。

非常感谢您的帮助。谢谢。

5个回答

10

echoread 命令都是通过文本界面工作的,例如脚本运行的终端窗口。如果在 OS X Service 中运行脚本,则没有类似终端的界面,因此两个命令都不会有任何用处。(我不知道 Keyboard Maestro 是否相似)。通常,从这种情况下进行交互的最简单方法是使用 osascript 命令通过 AppleScript。

name="$(osascript -e 'Tell application "System Events" to display dialog "Enter the project name:" default answer ""' -e 'text returned of result' 2>/dev/null)"
if [ $? -ne 0 ]; then
    # The user pressed Cancel
    exit 1 # exit with an error status
elif [ -z "$name" ]; then
    # The user left the project name blank
    osascript -e 'Tell application "System Events" to display alert "You must enter a project name; cancelling..." as warning'
    exit 1 # exit with an error status
fi

mkdir -p ~/Desktop/$name
mkdir -p ~/Desktop/$name/subfolder1
mkdir -p ~/Desktop/$name/subfolder2

(注意:我更喜欢在shell中使用小写变量名,以避免可能与特殊变量(如PATH等)发生冲突。)


太好了,我知道有一种更聪明的方法来完成这个。感谢你提供的osascript提示和上面的示例! - patrick
抱歉,您能告诉我这些命令中的“fi”是什么意思吗? - nullmicgo
@nullmicgo:fi标记着if块的结束——它是“if”倒过来拼写的,类似于case ... esac块。 - Gordon Davisson
这个能用来生成一个没有“取消”按钮的输入对话框吗?编辑:是的,可以。我在这个有用的参考文档中找到了答案。 - Ricardo Sanchez-Saez
@RicardoSánchez-Sáez:记录一下,将default answer ""'更改为default answer "" buttons {"OK"} default button "OK"' - Gordon Davisson

3
注意:@Gordon Davisson的答案值得认可,但以下改进使代码更加健壮(我试图编辑原始帖子,但被拒绝了)。
改进:
- 输入中的前导和尾随空格被修剪。 - 防止仅由空格组成的输入。 - 空输入或仅包含空格的输入在警告后将用户返回到提示符。
代码:
while :; do # Loop until valid input is entered or Cancel is pressed.
    name=$(osascript -e 'Tell application "System Events" to display dialog "Enter the project name:" default answer ""' -e 'text returned of result' 2>/dev/null)
    if (( $? )); then exit 1; fi  # Abort, if user pressed Cancel.
    name=$(echo -n "$name" | sed 's/^ *//' | sed 's/ *$//')  # Trim leading and trailing whitespace.
    if [[ -z "$name" ]]; then
        # The user left the project name blank.
        osascript -e 'Tell application "System Events" to display alert "You must enter a non-blank project name; please try again." as warning' >/dev/null
        # Continue loop to prompt again.
    else
        # Valid input: exit loop and continue.
        break
    fi
done

2

我假设脚本不是在交互式shell中运行,这意味着你将无法与read -e交互。

我没有一个OSX系统来尝试这个,但你可以尝试使用CocoaDialog来创建一个图形化对话框。

未经测试的示例:

#!/bin/bash
NAME=`CocoaDialog standard-inputbox --title "Project Name" --no-newline --no-cancel --informative-text "Enter the project name"`
mkdir -p ~/Desktop/$NAME/subfolder1
mkdir -p ~/Desktop/$NAME/subfolder2

感谢您提供使用CocoaDialog的建议,并确认当我离开shell时没有交互是可能的。作为一个编程新手,我仍然更喜欢使用内置工具而不是安装另一个应用程序。 - patrick

1

尝试将shebang行更改为#!/bin/bashread是bash内置命令,而您当前未使用bash运行脚本。 /bin/sh实际上可能是指向/bin/bash的链接,但根据维基百科的说法,这取决于您所使用的OS X版本。

您的脚本在bash下应该可以正常工作。


仍然不起作用 - 只有两个子文件夹被创建。我想这是因为我没有在 shell 中触发它,所以没有提示我。 - patrick
我沒意識到它是這樣運作的,我以為你是在終端機上啟動進程。對此非常抱歉! - Eduardo Ivanec
没问题。我应该更加准确,感谢你的帮助。 - patrick

0

NAME是空的还是只是将$NAME输出为字符串?如果是后者,您应该尝试~/Desktop/$(NAME)

此外,您可以尝试XDialog(或MacOS中的其他工具)。有很多关于如何使用它进行输入处理的资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接