OS X的Bash脚本绝对路径

The*_*uck 85 macos bash path

我试图获取OS X上当前运行脚本的绝对路径.

我看到很多回复readlink -f $0.但是,由于OS X readlink与BSD相同,它只是不起作用(它适用于GNU的版本).

有没有开箱即用的解决方案?

Ole*_*eev 104

这三个简单的步骤将解决这个问题以及许多其他OS X问题:

  1. 安装Homebrew
  2. brew install coreutils
  3. grealpath .

(3)可以改为just realpath,见(2)输出

  • @omouse这个问题特别提到了"开箱即用的解决方案"(适用于OS X).无论coreutils有多棒,它在OS X上都不是"开箱即用",所以答案不是很好.这不是一个好的coreutils是什么,或者它是否比OS X更好的问题.有"开箱即用"的解决方案`$(cd"$(dirname"$ 0")"; pwd -P) `对我来说很好. (6认同)
  • @JasonS GNU Coreutils太好了*不能*使用.它包括很多很棒的工具.实际上,如果没有它,Linux内核就没用了,为什么有些人称它为GNU/Linux.Coreutils太棒了.优秀的答案这应该是选定的答案. (5认同)
  • 这解决了问题,但需要安装您可能不需要或不需要的东西,或者可能不在目标系统上的东西,即OS X (2认同)
  • OS X的“功能”之一是目录和文件名不区分大小写。结果,如果您有一个名为“ XXX”的目录和一个“ cd xxx”目录,则“ pwd”将返回“ ... / xxx”。除此答案外,当您真正想要的是“ XXX”时,以上所有解决方案都将返回“ xxx”。谢谢! (2认同)

Joh*_*ica 76

有一个realpath()C函数可以完成这项工作,但我没有在命令行上看到任何可用的东西.这是一个快速而又脏的替代品:

#!/bin/bash

realpath() {
    [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}

realpath "$0"
Run Code Online (Sandbox Code Playgroud)

如果它以a开头,则逐字打印路径/.如果不是它必须是相对路径,所以它$PWD在前面.的#./部分剥去./从的前面$1.

  • `realpath ../ something`返回`$ PWD /../ something` (13认同)
  • 请注意,这不会取消引用符号链接. (7认同)
  • ``command -v realpath>/dev/null 2>&1 || realpath(){...}`` (5认同)

Geo*_*xon 24

啊.我发现之前的答案有点缺乏原因:特别是,它们没有解决多级符号链接,而且它们非常"Bash-y".虽然最初的问题明确要求"Bash脚本",但它也提到了Mac OS X的类BSD,非GNU readlink.所以这是尝试一些合理的可移植性(我用bash检查它为'sh'和破折号),解析任意数量的符号链接; 它也应该与路径中的空格一起使用,虽然我不确定该实用程序本身的基本名称是否有空格,所以也许,嗯,避免这种情况?

#!/bin/sh
realpath() {
  OURPWD=$PWD
  cd "$(dirname "$1")"
  LINK=$(readlink "$(basename "$1")")
  while [ "$LINK" ]; do
    cd "$(dirname "$LINK")"
    LINK=$(readlink "$(basename "$1")")
  done
  REALPATH="$PWD/$(basename "$1")"
  cd "$OURPWD"
  echo "$REALPATH"
}
realpath "$@"
Run Code Online (Sandbox Code Playgroud)

希望对某人有用.

  • 我只建议对函数内部定义的变量使用`local`,以免污染全局命名空间。例如`本地OURPWD = ...`。至少适用于 bash。 (3认同)
  • 这并不像“realpath”那样处理符号链接和“..”父引用。安装了自制软件“coreutils”后,尝试“ln -s /var/log /tmp/linkexample”,然后尝试“realpath /tmp/linkexample/../”;这会打印“/private/var”。但是你的函数会生成“/tmp/linkexample/..”,因为“..”不是符号链接。 (2认同)

xpt*_*xpt 15

我检查了每个答案,但错过了 Jason S 于 2016 年 7 月 14 日 3:12 发表的最好的一个(恕我直言),离开了评论字段。

所以,如果像我这样的人倾向于检查答案,但没有时间仔细查看每一条评论:

$( cd "$(dirname "$0")" ; pwd -P )
Run Code Online (Sandbox Code Playgroud)

帮助:

NAME
     pwd -- return working directory name

SYNOPSIS
     pwd [-L | -P]

DESCRIPTION
     The pwd utility writes the absolute pathname of the current working
     directory to the standard output.

     Some shells may provide a builtin pwd command which is similar or identi-
     cal to this utility.  Consult the builtin(1) manual page.

     The options are as follows:

     -L      Display the logical current working directory.

     -P      Display the physical current working directory (all symbolic
             links resolved).
Run Code Online (Sandbox Code Playgroud)


小智 11

Python解决方案的更多命令行友好变体:

python -c "import os; print(os.path.realpath('$1'))"
Run Code Online (Sandbox Code Playgroud)

  • 我很生气,但使用了 `python -c "import os; import sys; print(os.path.realpath(sys.argv[1]))"` (3认同)
  • 以防万一有人疯狂到为单个命令启动python解释器...... (2认同)

acr*_*ing 7

使用Python来获取它:

#!/usr/bin/env python
import os
import sys

print(os.path.realpath(sys.argv[1]))
Run Code Online (Sandbox Code Playgroud)


4ae*_*1e1 6

我一直在寻找在系统配置脚本中使用的解决方案,即在安装Homebrew之前运行.缺乏正确的解决方案我只是将任务卸载到跨平台语言,例如Perl:

script_abspath=$(perl -e 'use Cwd "abs_path"; print abs_path(@ARGV[0])' -- "$0")
Run Code Online (Sandbox Code Playgroud)

更常见的是我们真正想要的是包含目录:

here=$(perl -e 'use File::Basename; use Cwd "abs_path"; print dirname(abs_path(@ARGV[0]));' -- "$0")
Run Code Online (Sandbox Code Playgroud)


Log*_*ogu 6

abs_path () {    
   echo "$(cd $(dirname "$1");pwd)/$(basename "$1")"
}
Run Code Online (Sandbox Code Playgroud)

dirname将给出 的目录名称/path/to/file,即/path/to

cd /path/to; pwd 确保路径是绝对的。

basename将只给出文件名/path/to/file,即file.

  • 虽然此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的附加上下文可以提高其长期价值。 (2认同)

Waf*_*fle 5

因为有其他人指出的真实路径:

// realpath.c
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char* argv[])
{
  if (argc > 1) {
    for (int argIter = 1; argIter < argc; ++argIter) {
      char *resolved_path_buffer = NULL;
      char *result = realpath(argv[argIter], resolved_path_buffer);

      puts(result);

      if (result != NULL) {
        free(result);
      }
    }
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Makefile文件:

#Makefile
OBJ = realpath.o

%.o: %.c
      $(CC) -c -o $@ $< $(CFLAGS)

realpath: $(OBJ)
      gcc -o $@ $^ $(CFLAGS)
Run Code Online (Sandbox Code Playgroud)

然后编译make并输入一个软链接:
ln -s $(pwd)/realpath /usr/local/bin/realpath


Evg*_*pov 5

Mac OS X 的真实路径

realpath() {
    path=`eval echo "$1"`
    folder=$(dirname "$path")
    echo $(cd "$folder"; pwd)/$(basename "$path"); 
}
Run Code Online (Sandbox Code Playgroud)

具有相关路径的示例:

realpath "../scripts/test.sh"
Run Code Online (Sandbox Code Playgroud)

主文件夹示例

realpath "~/Test/../Test/scripts/test.sh"
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

61439 次

最近记录:

5 年,10 月 前