[macos] OS X의 Bash 스크립트 절대 경로

OS X에서 현재 실행중인 스크립트의 절대 경로를 얻으려고합니다.

에 대한 많은 답변을 보았습니다 readlink -f $0. 그러나 OS X readlink는 BSD와 동일하기 때문에 작동하지 않습니다 (GNU 버전에서 작동).

이에 대한 기본 솔루션이 있습니까?



답변

거기의 realpath()일을 할 것입니다 C의 기능은,하지만 난 명령 줄에서 사용할 수 아무것도 보이지 않아요. 다음은 빠르고 더러운 교체입니다.

#!/bin/bash

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

realpath "$0"

로 시작하는 경우 경로를 그대로 인쇄합니다 /. 그렇지 않은 경우 상대 경로 여야하므로 앞에 추가 $PWD됩니다. #./부분은 오프 스트립 ./의 전면에서 $1.


답변

다음 세 가지 간단한 단계를 통해이 문제와 다른 많은 OS X 문제를 해결할 수 있습니다.

  1. Homebrew 설치
  2. brew install coreutils
  3. grealpath .

(3)으로 변경 될 수 있습니다. realpath(2) 출력 참조


답변

으. 나는 몇 가지 이유로 인해 이전 답변이 약간 필요하다는 것을 발견했습니다. 특히, 그들은 여러 수준의 심볼릭 링크를 해결하지 않으며 매우 “Bash-y”입니다. 원래 질문은 “Bash 스크립트”를 명시 적으로 요구하지만 Mac OS X의 BSD와 유사한 비 GNU에 대해서도 언급 readlink합니다. 그래서 여기에 임의의 수의 심볼릭 링크를 해결하는 합리적인 이식성에 대한 시도가 있습니다 (bash로 ‘sh’와 dash로 확인했습니다). 유틸리티 자체의 기본 이름에 공백이 있으면 동작을 확신 할 수 없지만 경로의 공백과 함께 작동해야합니다.

#!/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 "$@"

누군가에게 유용 할 수 있기를 바랍니다.


답변

명령 줄 친화적 인 Python 솔루션 변형 :

python -c "import os; print(os.path.realpath('$1'))"


답변

시스템 프로비저닝 스크립트, 즉 Homebrew가 설치되기 전에 실행되는 솔루션을 찾고있었습니다. 적절한 솔루션이 없으면 Perl과 같은 크로스 플랫폼 언어로 작업을 오프로드합니다.

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

더 자주 우리가 실제로 원하는 것은 포함하는 디렉토리입니다.

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


답변

가 있기 때문에 realpath 등의 뾰족한 밖으로있다 :

// 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;
}

Makefile :

#Makefile
OBJ = realpath.o

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

realpath: $(OBJ)
      gcc -o $@ $^ $(CFLAGS)

그런 다음 다음으로 컴파일 make하고 소프트 링크를 넣습니다.
ln -s $(pwd)/realpath /usr/local/bin/realpath


답변

Python을 사용하여 얻으십시오.

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

print(os.path.realpath(sys.argv[1]))