Check if a file is executable

后端 未结 6 830
粉色の甜心
粉色の甜心 2020-11-27 16:11

I am wondering what\'s the easiest way to check if a program is executable with bash, without executing it ? It should at least check whether the file has execute rights, a

6条回答
  •  谎友^
    谎友^ (楼主)
    2020-11-27 17:08

    This might be not so obvious, but sometime is required to test the executable to appropriately call it without an external shell process:

    function tkl_is_file_os_exec()
    {
      [[ ! -x "$1" ]] && return 255
    
      local exec_header_bytes
      case "$OSTYPE" in
        cygwin* | msys* | mingw*)
          # CAUTION:
          #   The bash version 3.2+ might require a file path together with the extension,
          #   otherwise will throw the error: `bash: ...: No such file or directory`.
          #   So we make a guess to avoid the error.
          #
          {
            read -r -n 4 exec_header_bytes 2> /dev/null < "$1" ||
            {
              [[ -x "${1%.exe}.exe" ]] && read -r -n 4 exec_header_bytes 2> /dev/null < "${1%.exe}.exe"
            } ||
            {
              [[ -x "${1%.com}.com" ]] && read -r -n 4 exec_header_bytes 2> /dev/null < "${1%.com}.com"
            }
          } &&
          if [[ "${exec_header_bytes:0:3}" == $'MZ\x90' ]]; then
            # $'MZ\x90\00' for bash version 3.2.42+
            # $'MZ\x90\03' for bash version 4.0+
            [[ "${exec_header_bytes:3:1}" == $'\x00' || "${exec_header_bytes:3:1}" == $'\x03' ]] && return 0
          fi
        ;;
        *)
          read -r -n 4 exec_header_bytes < "$1"
          [[ "$exec_header_bytes" == $'\x7fELF' ]] && return 0
        ;;
      esac
    
      return 1
    }
    
    # executes script in the shell process in case of a shell script, otherwise executes as usual
    function tkl_exec_inproc()
    {
      if tkl_is_file_os_exec "$1"; then
        "$@"
      else
        . "$@"
      fi
      return $?
    }
    

    myscript.sh:

    #!/bin/bash
    
    echo 123
    
    return 123
    

    In Cygwin:

    > tkl_exec_inproc /cygdrive/c/Windows/system32/cmd.exe /c 'echo 123'
    123
    > tkl_exec_inproc /cygdrive/c/Windows/system32/chcp.com 65001
    Active code page: 65001
    > tkl_exec_inproc ./myscript.sh
    123
    > echo $?
    123
    

    In Linux:

    > tkl_exec_inproc /bin/bash -c 'echo 123'
    123
    > tkl_exec_inproc ./myscript.sh
    123
    > echo $?
    123
    

提交回复
热议问题