如何提示用户输入名称以创建文件夹(bash | shell 脚本)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9180476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:30:29  来源:igfitidea点击:

How to prompt a user for a name to create a folder (bash | shell script)?

macosbashshelldirectory-structure

提问by patrick

First off, this is my first go at shell scripting. I have only experience in HTML and CSS :]

首先,这是我第一次接触 shell 脚本。我只有 HTML 和 CSS 方面的经验:]

What I want to do is setup a simple folder structureand prompt the user in a dialog box to set a namefor the root folder. I'll trigger this shell script via an OS X Service or a Keyboard Maestro hotkey.

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

This is what I've come up with so far:

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

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

Obviously there's some error - the variable won't get passed on and the root folder isn't created. I also read that I should use "dialog" to ask for the input, but I wasn't capable of writing something that works.

显然有一些错误 - 变量不会被传递并且没有创建根文件夹。我还读到我应该使用“对话框”来请求输入,但我无法写出有效的东西。

Your help is greatly appreciated. Thanks.

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

回答by Gordon Davisson

The echoand readcommands both work via a text interface, such as the Terminal window the script is running in. If you run a script in an OS X Service, there's no Terminal-like interface, so neither command does anything useful. (I don't know about Keyboard Maestro, but I assume it's similar.) The simplest way to interact from a situation like this is generally to use AppleScript via the osascriptcommand:

echoread命令通过文本界面,如脚本运行的终端窗口里工作。如果你运行在OS X服务的脚本,有没有类似于终端的界面,所以无论命令执行任何有用的东西。(我不了解 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

(Note: I prefer to use lowercase variable names in the shell to avoid possible conflicts with special variables like PATH etc...)

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

回答by mklement0

Note: @Gordon Davisson's answer deserves the credit, but here are some improvements that make the code more robust (I tried to edit the original post, but it was rejected).

注意:@Gordon Davisson 的回答值得称赞,但这里有一些改进可以使代码更加健壮(我尝试编辑原始帖子,但被拒绝)。

Improvements:

改进:

  • leading and trailing whitespace is trimmed from the input
  • whitespace-only input is prevented
  • empty or whitespace-only input returns user to prompt after warning
  • 从输入中修剪前导和尾随空格
  • 禁止纯空格输入
  • 空或纯空格输入在警告后返回用户提示

Code:

代码:

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

回答by Shawn Chin

I'm assuming the script isn't being run in an interactive shell, which means you will not be able to interact with read -e.

我假设脚本没有在交互式 shell 中运行,这意味着您将无法与read -e.

I don't have an OSX box to try this out, but you could try using CocoaDialogfor a graphical dialog box.

我没有 OSX 框来尝试这个,但你可以尝试使用CocoaDialog作为图形对话框。

Untested example:

未经测试的例子:

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

回答by Eduardo Ivanec

Try changing the shebang line to #!/bin/bash. readis a bash builtin, and you're not running your script with bash currently. /bin/shmay actually be a link to /bin/bash, but according to Wikipedia this depends on the specific version of OS X that you have.

尝试将 shebang 行更改为#!/bin/bash. read是一个内置的 bash,并且您当前没有使用 bash 运行您的脚本。/bin/sh实际上可能是指向 的链接/bin/bash,但根据维基百科,这取决于您拥有的特定 OS X 版本。

Your script as it is should work correctly under bash.

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

回答by kaoD

NAME is empty or it's just outputting $NAME as a string? If it's the latter you should try ~/Desktop/$(NAME)

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

Also, you should try XDialog(or whatever is the tool in MacOS.) There are plenty of resources about using it for input handling.

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