Bash 别名与三元?

问题描述 投票:0回答:2

仍在尝试 bash 编码并尝试创建一个 1 liner 别名到:

  • 如果在没有参数的情况下输入“perms”,它会执行
    stat -c '%a - %n' *
  • 否则,如果使用参数输入“perms”,它会执行
    stat -c '%a - %n' <parameter>
  • 目标是如果没有添加参数,显示所有文件/文件夹的权限,否则显示指定文件/文件夹的权限。

到目前为止,我已经使用了 2 个不同的版本,但它们都产生了相同的结果;添加参数后效果很好;没有参数,它不会添加

*
并且命令说它需要一个参数。所以出于某种原因,“if true”部分没有填充
$a
var,但“else”部分确实填充了它。

alias perms="a=$(if [ -z '$@' ]; then *; else $@; fi) stat -c '%a - %n' $a"

alias perms="a=$([[ -z '$1' ]] && '*' || $1) stat -c '%a - %n' $a"
bash zsh alias conditional-operator zsh-alias
2个回答
2
投票

这应该是一个函数。 (大多数 人们尝试使用别名的东西应该是函数。)

perms () {
  if [ $# -eq 0 ]; then
    stat -c '%a -%n' *
  else
    stat -c '%a - %n' "$@"
  fi
}

0
投票

你应该使用一个函数。你可以这样做:

perms() { files=( * ); stat -c '%s - %n' "${@:-${files[@]}}"; }

将当前目录的内容存储在数组中

files[]
然后打印
"$@"
如果填充或
"${files[@]}"
否则。这样做的问题是,如果您的目录中没有文件,那么
*
将按字面意思传递给
stat
并且失败抱怨没有名为
*
的文件并以失败状态退出,我认为这两者都是不可取的行为,例如在空目录中运行:

$ perms() { files=( * ); stat -c '%s - %n' "${@:-${files[@]}}"; }
$ perms
stat: cannot stat '*': No such file or directory
$ echo $?
1

您可以添加

shopt -s nullglob
来尝试解决该问题,但是 stat 将失败并抱怨空参数:

$ perms() { shopt -s nullglob; files=( * ); stat -c '%s - %n' "${@:-${files[@]}}"; }
$ perms
stat: cannot stat '': No such file or directory
$ echo $?
1

所以仅靠这一点并不能解决问题(并且您还需要在离开函数之前将

nullglob
设置回之前的值,这样无论如何改变都不够)。

所以,我建议您改为这样做:

$ perms() {
    local files
    if (( $# > 0 )); then
        files=( "$@" )
    else
        local orig_nullglob=$(shopt -p nullglob)
        shopt -s nullglob
        files=( * )
        $orig_nullglob
    fi
    if (( "${#files[@]}" > 0 )); then
        stat -c '%s - %n' "${files[@]}"
    fi
}

$ > foo
$ > bar

$ perms foo
0 - foo

$ perms
0 - bar
0 - foo

$ rm foo bar

$ perms
$ echo $?
0

如果函数中的命令之一失败或者您向它传递一个不退出的文件名参数,它只会以失败退出状态退出,我认为这是理想的行为:

$ perms nonsense
stat: cannot stat 'nonsense': No such file or directory
$ echo $?
1

以上假设您在标记时使用

bash
。如果您实际上正在使用
zsh
作为您也标记的,那么我知道需要进行哪些更改。

© www.soinside.com 2019 - 2024. All rights reserved.