在 *nix 中缩短命令选项的最佳方法

在 *nix 中缩短命令选项的最佳方法

在 *nix(别名、脚本等)中,对于没有提供缩写形式的命令,缩短可用选项的最佳方法是什么?

这个想法是将命令以某种方式包装起来,以便能够只缩写第一个选项。此外,还允许使用原始选项。

常规命令:

 > command option1 file.txt
 > command option2 file.txt

使用包装器:

> command o1 file.txt
> command o2 file.txt

下面是一些伪代码来描述我想到的一个可能的解决方案,即使用与命令同名的 shell 脚本并将其放在 PATH 的首位。

 if $first_argument == "o1"
    call <command> option1 $additional_arguments
 else if $first_argument == "o2"
    call <command> option2 $additional_arguments
 else
    call <command> $first_argument $additional_arguments

这可能吗?

答案1

您可以在 ~/.bashrc 文件中创建别名。例如,创建一个文件夹的 7-zip 存档,该文件夹通常是

7z a -m0=lzma2 -mx=9 -ms=on -mf=on -mtc=on archive_name.7z folder_name

在你的 ~/.bashrc 中输入:

alias 7zipfolder='7z a -m0=lzma2 -mx=9 -ms=on -mf=on -mtc=on'

之后,你就可以这样做,

7zipfolder archive_name.7z folder_name

您必须注销并重新登录才能使其生效,或者执行 source ~/.bashrc

哈哈哈:)

==== 编辑:考虑到下面的回复,嗯,我想你可以这样做,如果你修改 PATH 来首先查看你的个人脚本文件夹,比如

PATH=~/.shortcommands:$PATH

然后,您可以创建与安装在 /usr/sbin 中的脚本同名的脚本,循环所有参数,扩展所需的参数,然后使用翻译后的选项集在其绝对路径中调用“真实”脚本/应用程序来结束。

例如

  7z --folder Documents.7z Documents/

调用

  ~/.shortcommands/7z

将所有内容翻译为:

  /usr/bin/7z a -m0=lzma2 -mx=9 -ms=on -mf=on -mtc=on Documents.7z Documents/

脚本本身会遍历参数列表,然后转换符合您需求的内容。您可能还远不能在原始命令上创建“shell”,但显然这不是您想要的。不确定您对 bash 脚本的熟练程度,但那里有大量非常好的资源。仅作为参数迭代的示例,以下是我目前正在编写的脚本的片段,该脚本创建/检查其他文件的奇偶校验数据和校验和文件:

# Iterate arguments while shifting off those meant for us, leaving behind files to process.
# No clue how to directly index on the arguments array, so I copy it:
args=("$@")
files=()
files_count=0

# Then we iterate over each argument, collecting anything that's for us, and adding files
# to our files array, making sure to get absolute paths should we somehow get relative ones
# (e.g. from Nautilus or the commandline):
for ((i=0; $i<$#; i++)); do
        argument=${args[$i]}
        # How deep to go into FILE before starting to create/check protection files:
        if [ "$argument" = "-d" -o "$argument" = "--depth" ]; then
                # Seek to the next argument, i.e. the value:
                let "i=i+1"
                # We'll get an error if we try to just grab the next argument and it isn't there:
                if [ $i -eq $# ]; then
                        print_argument_error "${args[$i-1]} needs a value."
                else
                        target_depth="${args[$i]}"
                        # Okay, so is the value sane?
                        if [[ ! $target_depth =~ ^[1-9][0-9]{0,}$ ]]; then
                                print_argument_error "${args[$i-1]} must be 1 or higher."
                        fi
                fi
        # Whether or not to include output from our client commands, too:
        elif [ "$argument" = "-v" -o "$argument" = "--verbose" ]; then
                print_client_output=1
        # Whether or not to verify files:
        elif [ "$argument" = "-V" -o "$argument" = "--verify" ]; then
                check=1
        # Whether or not to create validation files:
        elif [ "$argument" = "-C" -o "$argument" = "--create" ]; then
                verify=1
        # Whether or not to repair files when possible:
        elif [ "$argument" = "-R" -o "$argument" = "--repair" ]; then
                verify=1
                repair=1
        # That's all the arguments we understand, the rest must be files:
        else
                # So we assume anything but an option is an input file or dir. Get the item:
                item="$argument"

                # If it's a file, we get its directory location and convert it to absolute,
                # then prepend the file name back onto that before pushing it onto our files
                # array. If it's a dir, we just convert it to absolute before pushing it:
                if [ -f "$item" ]; then
                        dir="`dirname "$item"`"
                        files[${files_count}]="`cd "$dir"; pwd`/`basename "$item"`"
                        let "files_count=files_count+1"
                elif [ -d "$item" ]; then
                        files[${files_count}]="`cd "$item"; pwd`"
                        let "files_count=files_count+1"
                fi
        fi
done

答案2

这在一定程度上取决于命令如何解析其选项。对于使用 popt 参数解析库构建的程序,有一个内置的别名机制,可以使用主目录中的 rc 文件创建扩展到现有选项的别名选项。不幸的是,popt 文档并不完全面向最终用户,而是面向希望在其程序中使用该库的开发人员。但是,有关和的信息/etc/popt可以在手册页的第 3 部分中${HOME}/.popt找到popt选项别名部分。

当然,这仅适用于首先使用 popt 构建的程序。如上所述,没有通用机制,因为没有一种参数解析机制可供所有程序使用。包装器脚本和别名是没有 popt 或类似 popt 的选项别名机制的程序的资源。

答案3

这是为了让这些更容易输入吗?你可能想看看可编程命令行完成.它可以使你的打字更有效率。

相关内容