【问题标题】:GNU ls from Coreutils missing OS X ACL implementation来自 Coreutils 的 GNU ls 缺少 OS X ACL 实现
【发布时间】:2014-10-27 10:48:52
【问题描述】:

我正在使用brew 来检索和安装通用 GNU 版本的终端命令和实用程序 brew install coreutils
然后在我的 .bash_profile 中包含他们的 PATH

if [  -d $(brew --prefix coreutils)/libexec/gnubin  ]; then
    PATH="$(brew --prefix coreutils)/libexec/gnubin:$PATH"
fi

到目前为止一切顺利,我可以使用 GNU 版本的 coreutils。
问题来自ls。 Apple 实现了 ACL,但 GNU ls 上没有实现。我通过多次敲我的头发现了这一点,但不明白为什么(例如)ls -le@ 会给我错误ls: invalid option -- 'e'

所以现在我明白 GNU ls 是问题所在。

问题
如何获取所有 coreutils 但ls? 我想使用 Apple 版本的 ls,但继续使用其余的 coreutils。如何修改我的.bash_profile 来实现这一点?

编辑:

如果我创建一个标志来了解我当前是否使用 coretuils,因此我将创建一个别名:

ls_flag=false
if [[  $(brew) &&  -d  $(brew --prefix coreutils)/libexec/gnubin  ]]; then
    PATH="$(brew --prefix coreutils)/libexec/gnubin:$PATH"
    ls_flag=true
fi

export PATH

if [[ ls_flag -eq true ]]; then
   alias ls=/bin/ls
fi

如果我在这里停止我的.bash_profile,这将起作用。但是另一个问题来自以下条件。我使用它们来了解我使用的是 GNU ls 还是 Apple ls,并选择了正确的选项来为 ls 命令着色:

# Detect which `ls` flavour is in use
if ls --color > /dev/null 2>&1; then # GNU `ls`
    alias ls='ls --color=always'
    # load my color scheme (it only works with GNU ls)
    # dircolors only work with coreutils
    eval `dircolors  ~/.dotfiles/data/dircolors`
else # OS X `ls`
    alias ls='ls -G'
fi

所以,此时 ls 应该是:
1) alias ls=/bin/ls # 从第一个条件 ls_flag == true
2) alias ls='ls -G' # 从第二个条件 "if ls --color" (false)

但是如果我提示 ls -@ 仍然会抛出一个错误,告诉我我仍在使用 GNU ls...想知道为什么最后一个别名会覆盖以前的别名...

【问题讨论】:

  • 你为什么不直接删除(或重命名,或chmod -x)coreutils'ls
  • 另一种可能性是在您的/usr/local/bin(或在 OSX 上可能更合适的其他目录)中链接您要使用的 coreutils 命令(因此不是 ls),确保出现此目录在您的 PATH 变量中的 /bin 之前。
  • @gniourf_gniourf 我想使用 coreutils 中的所有命令(除了 ls),这就是 PATH="$(brew --prefix coreutils)/libexec/gnubin:$PATH" 会做的。手动链接所有这些,但 ls 似乎不是一个好的解决方案。假设有 100 个命令,而不是删除我不需要的唯一 1 个命令,而是建议将 99 个我需要的..链接到很多工作
  • 那我的其他建议怎么样?即,从 coreutils 重命名/删除/chmod -x ls
  • 顺便说一句,链接除一个以外的所有内容相当简单:链接所有内容,然后删除您不想要的链接。

标签: macos bash homebrew ls gnu-coreutils


【解决方案1】:

这是错误的

if [[ ls_flag -eq true ]]; then
   alias ls=/bin/ls
fi

您缺少$ls_flag$-eq 用于[[ ... ]] 内的数字比较

因为“真”和“假”是命令,所以你要写

if $ls_flag; then
   alias ls=/bin/ls
fi

或者,更简洁

$ls_flag && alias ls=/bin/ls

【讨论】:

  • 你说得对,我的 bash 脚本知识很尴尬
【解决方案2】:

你可以创建一个别名:

alias ls=/bin/ls

【讨论】:

  • 这行不通。首先因为它应该是alias ls=/bin/ls,但如果我which ls 我得到/usr/local/opt/coreutils/libexec/gnubin/ls
  • 如果你输入ls 会发生什么?使用which 不是重点。
  • 如果我输入 ls -@ 我会收到错误信息,表明我仍在使用 GNU ls。但是,如果我在本地 shell 中使用别名,那么它将起作用。问题来自在 bash_profile 中定义别名。除了 ls 命令之外,没有一种干净的方法可以告诉导出 PATH 吗?
  • 这是我能想到的唯一方法。
  • 好的,问题来自我对 ls 所做的其他别名,我会更新问题
猜你喜欢
  • 2018-12-14
  • 1970-01-01
  • 2011-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多