为什么$(date +%N)有时会返回“N”而不是以纳秒为单位的当前时间戳?

时间:2014-10-29 03:53:50

标签: macos homebrew zsh

我的.zshrc文件中的以下函数(在OS X上,使用coreutils日期实现):

# Display timestamped debugging messages when ZSHDBG is enabled.
function zshdbg () {
  if [[ $ZSHDBG -eq 1 ]]; then
    purple="\x1b[35;01m"
    reset="\x1b[39;49;00m"
    now=$(date '+%F %T')
    nanoseconds=$(date +%N)

    # For some reason on OSX, %N is sometimes returned as "N" rather than the
    # current nanosecond timestamp. This is a nasty hack for providing a
    # default value in those unfortunate cases.
    # if [[ "$nanoseconds" -eq 'N' ]]; then
    #   nanoseconds='000000000'
    # fi

    echo "$purple$now [$nanoseconds] $1$reset"
  fi
}

由于某种原因,纳秒有时会返回为“N”:

2014-10-28 21:45:42 [N] Antigen installation detected.
2014-10-28 21:45:42 [N] Last update on . Current date 2014-10-28 21:45:42. It's been  days since the last update.
2014-10-28 21:45:42 [N] Loading antigen.
2014-10-28 21:45:42 [N] Setting oh-my-zsh as the default antigen plugin repository.
2014-10-28 21:45:42 [N] Enabling OS X specific plugins.
2014-10-28 21:45:42 [N] Loading plugin zsh-users/zsh-syntax-highlighting.
2014-10-28 21:45:42 [N] Loading theme jonathan.
2014-10-28 21:45:42 [N] Applying the antigen configuration.
2014-10-28 21:45:42 [N] Setting default exports.
2014-10-28 21:45:43 [N] OS X detected, executing OS specific configuration.
2014-10-28 21:45:43 [N] Homebrew detected. Configuring paths.
2014-10-28 21:45:43 [084632000] Finished loading .zshrc.

这是使用coreutils date命令:

which date
/usr/local/opt/coreutils/libexec/gnubin/date

但是,如果我明确地调用/ bin / date,我仍然会得到类似的行为:

2014-10-28 21:50:47 [N] Antigen installation detected.
2014-10-28 21:50:47 [N] Last update on . Current date 2014-10-28 21:50:47. It's been  days since the last update.
2014-10-28 21:50:47 [N] Loading antigen.
2014-10-28 21:50:47 [N] Setting oh-my-zsh as the default antigen plugin repository.
2014-10-28 21:50:47 [N] Enabling OS X specific plugins.
2014-10-28 21:50:47 [N] Loading plugin zsh-users/zsh-syntax-highlighting.
2014-10-28 21:50:47 [N] Loading theme jonathan.
2014-10-28 21:50:47 [N] Applying the antigen configuration.
2014-10-28 21:50:47 [N] Setting default exports.
2014-10-28 21:50:47 [N] OS X detected, executing OS specific configuration.
2014-10-28 21:50:47 [N] Homebrew detected. Configuring paths.
2014-10-28 21:50:47 [N] Finished loading .zshrc.

我一直在挖掘日期,zsh和homebrew的coreutils的文档,但没有找到任何相关的东西。有什么想法可能会发生这种情况吗?

3 个答案:

答案 0 :(得分:1)

OS X提供的date的实现不支持+N,因此/bin/date +N只打印“N”。我怀疑你的PATH不一致,特别是在/usr/local/opt/coreutils/libexec/gnubin之前/bin没有(总是)列出。试试这个:

# Display timestamped debugging messages when ZSHDBG is enabled.
function zshdbg () {
  if [[ $ZSHDBG -eq 1 ]]; then
    purple="\x1b[35;01m"
    reset="\x1b[39;49;00m"
    now=$(date '+%F %T')
    nanoseconds=$(/usr/local/opt/coreutils/libexec/gnubin/date +%N)

    echo "$purple$now [$nanoseconds] $1$reset"
  fi
}

如果修复了它,你应该试着找出与PATH混淆的东西,因为这可能不是唯一的效果......

答案 1 :(得分:0)

在稍微调整一下之后,我发现以下工作:

function zshdbg () {
  if [[ $ZSHDBG -eq 1 ]]; then
    purple="\x1b[35;01m"
    reset="\x1b[39;49;00m"
    now=$(date '+%F %T')
    nanoseconds=$(date +%N)

    echo $purple$now" ["$nanoseconds"] "$1$reset
  fi
}

它生成输出:

2014-10-28 22:27:32 [647272000] Antigen installation detected.
2014-10-28 22:27:32 [663708000] Last update on 1414545789. Current date 1414556852. It's been  days since the last update.
2014-10-28 22:27:32 [669752000] Loading antigen.
2014-10-28 22:27:32 [681586000] Setting oh-my-zsh as the default antigen plugin repository.
2014-10-28 22:27:32 [807303000] Enabling OS X specific plugins.
2014-10-28 22:27:32 [944470000] Loading plugin zsh-users/zsh-syntax-highlighting.
2014-10-28 22:27:33 [034537000] Loading theme jonathan.
2014-10-28 22:27:33 [125400000] Applying the antigen configuration.
2014-10-28 22:27:33 [171657000] Setting default exports.
2014-10-28 22:27:33 [303480000] Finished loading .zshrc.

在所有情况下都能正确生成纳秒。不确定到底发生了什么。它可能与围绕$ nanoseconds变量替换格式化括号的方式有关。

答案 2 :(得分:0)

从版本4.3.12(2011)开始,zshepochtime模块中包含EPOCHREALTIME数组和zsh/datetime变量,因此您不需要调用外部date命令(运行几千纳秒)。

$ zmodload zsh/datetime
$ strftime "%F %T [$epochtime[2]]" $epochtime[1]
2014-10-31 16:17:13 [698637482]