해당 명령이 ksh에 내장된 명령인지 확인하세요.

해당 명령이 ksh에 내장된 명령인지 확인하세요.

명령이 내장 명령인지 확인하는 방법은 무엇입니까 ksh?

; 을 tcsh사용할 수 있으며 일부 에서는 ;wherezshbashtype -a현대의ksh버전을 사용할 수 있습니다 whence -av.

내가 원하는 것은 다음과 같이 동작하는 모든 버전( 다른 "이전" 버전 포함 ) isbuiltin에서 작동하는 함수를 작성하는 것입니다.kshksh88ksh

  1. 여러 매개변수를 허용하고 각 매개변수가 내장되어 있는지 확인합니다.
  2. 0주어진 명령이 모두 내장되어 있으면 (성공)을 반환합니다.
  3. 첫 번째 비내장 명령에서 검사를 중지하고 반환 1(실패)한 후 stderr에 메시지를 인쇄합니다.

나는 이미 이와 같은 작동 기능을 가지고 zsh있으며 bash위 명령을 사용하고 있습니다.

이것이 내가 원하는 것입니다 ksh:

isbuiltin() {
  if [[ "$#" -eq 0 ]]; then
    echo "Usage: isbuiltin cmd" >&2
    return 1
  fi
  for cmd in "$@"
  do
    if [[ $cmd = "builtin" ]]; then
      #Handle the case of `builtin builtin`
      echo "$cmd is not a built-in" >&2
      return 1
    fi
    if ! whence -a "$cmd" 2> /dev/null | grep 'builtin' > /dev/null ; then
      echo "$cmd is not a built-in" >&2
      return 1
    fi
  done
}

이 기능은 ksh93에서 사용할 수 있습니다. 그러나 ksh88 버전은 해당 옵션이 모두 표시되도록 하는 옵션을 whence지원하지 않는 것 같습니다 . -a모든 항목을 표시할 수 없으므로 whence -v,하다명령이 내장되어 있는지 알려주지만, 같은 이름을 가진 별칭이나 함수가 없는 경우에만 해당됩니다.

질문:whence -avin 대신 다른 것을 사용할 수 있나요 ksh88?


해결책

허용되는 답변(하위 쉘 열기)을 사용하여 업데이트된 솔루션은 다음과 같습니다. .kshrc에 다음 내용을 입력합니다.

isbuiltin() {
  if [[ "$#" -eq 0 ]]; then
    printf "Usage: isbuiltin cmd\n" >&2
    return 1
  fi
  for cmd in "$@"
  do
    if (
         #Open a subshell so that aliases and functions can be safely removed,
         #  allowing `whence -v` to see the built-in command if there is one.
         unalias "$cmd";
         if [[ "$cmd" != '.' ]] && typeset -f | egrep "^(function *$cmd|$cmd\(\))" > /dev/null 2>&1
         then
           #Remove the function iff it exists.
           #Since `unset` is a special built-in, the subshell dies if it fails
           unset -f "$cmd";
         fi
         PATH='/no';
         #NOTE: we can't use `whence -a` because it's not supported in older versions of ksh
         whence -v "$cmd" 2>&1
       ) 2> /dev/null | grep -v 'not found' | grep 'builtin' > /dev/null 2>&1
    then
      #No-op.  Needed to support some old versions of ksh
      :
    else
      printf "$cmd is not a built-in\n" >&2
      return 1
    fi
  done
  return 0
}

나는 이것을 Solaris, AIX, HP-UX에서 ksh88로 테스트했습니다. 테스트한 모든 경우에 작동합니다. 또한 FreeBSD, Ubuntu, Fedora 및 Debian에서 최신 버전의 ksh를 사용하여 이를 테스트했습니다.

답변1

별칭이 걱정된다면 다음을 수행하십시오.

[[ $(unalias -- "$cmd"; type -- "$cmd") = *builtin ]]

( $(...)서브쉘 환경을 생성하므로 unalias해당 환경에서만 작동합니다.)

command unset -f -- "$cmd"기능에도 관심이 있다면 이전에 실행할 수도 있습니다 type.

답변2

ksh93해당 builtin명령을 구현하는 데 시간이 낭비될까봐 걱정됩니다 . 예를 들어 ksh version 93t 2008-11-04:

$ builtin
...creates list of all builtins

$ builtin jobs umask
...returns with exit code 0

$ builtin jobs time umask
...returns with exit code 1 and prints "builtin: time: not found"


또한 이 builtin명령은 내장 명령이므로 코드에서 이 특정 내장 명령을 제외한 테스트가 잘못된 것 같습니다.

답변3

#! /bin/sh

path_to_your_command=$(command -v your_command)

if [ "${path_to_your_command}" = 'your_command' ]; then
  echo 'your_command is a special builtin.'
else
  if [ -n "${path_to_your_command}" ]; then
    echo "your_command is a regular builtin, located at ${path_to_your_command}."
  else
    echo "your_command is not a builtin (and/or does not exist as it cannot be found in \$PATH)."
  fi
fi

관련 정보