我想知道什么是检查程序是否可以使用bash执行而不执行它的最简单方法?它至少应检查文件是否具有执行权限,并且具有相同的体系结构(例如,不是Windows可执行文件或其他不支持的体系结构,如果系统是32位,则不是64位,......)作为当前系统。
答案 0 :(得分:90)
查看各种test运算符(这是针对测试命令本身,但内置的BASH和TCSH测试或多或少相同)。
您会注意到-x FILE
表示 FILE存在且授予执行(或搜索)权限。
BASH,Bourne,Ksh,Zsh Script
if [[ -x "$file" ]]
then
echo "File '$file' is executable"
else
echo "File '$file' is not executable or found"
fi
TCSH或CSH脚本:
if ( -x "$file" ) then
echo "File '$file' is executable"
else
echo "File '$file' is not executable or found"
endif
要确定文件的类型,请尝试file命令。您可以解析输出以确切地查看它是什么类型的文件。 Word'o Warning :有时file
会返回多行。这是我的Mac上发生的事情:
$ file /bin/ls
/bin/ls: Mach-O universal binary with 2 architectures
/bin/ls (for architecture x86_64): Mach-O 64-bit executable x86_64
/bin/ls (for architecture i386): Mach-O executable i386
file
命令根据操作系统返回不同的输出。但是,单词executable
将出现在可执行程序中,通常也会显示该体系结构。
将上述内容与我在Linux机上的内容进行比较:
$ file /bin/ls
/bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), stripped
还有一个Solaris盒子:
$ file /bin/ls
/bin/ls: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, stripped
在这三个中,您会看到单词executable
和结构(x86-64
,i386
或SPARC
和32-bit
)。
非常感谢,这似乎是要走的路。在我将此标记为我的答案之前,您是否可以指导我在“文件”上执行哪种脚本shell检查(即,什么样的解析)以检查我是否可以执行程序?如果这样的测试在一般情况下难以制作,我至少想检查它是linux可执行文件还是osX(Mach-O)
在我的脑海中,你可以在BASH中做这样的事情:
if [ -x "$file" ] && file "$file" | grep -q "Mach-O"
then
echo "This is an executable Mac file"
elif [ -x "$file" ] && file "$file" | grep -q "GNU/Linux"
then
echo "This is an executable Linux File"
elif [ -x "$file" ] && file "$file" | grep q "shell script"
then
echo "This is an executable Shell Script"
elif [ -x "$file" ]
then
echo "This file is merely marked executable, but what type is a mystery"
else
echo "This file isn't even marked as being executable"
fi
基本上,我正在运行测试,如果成功,我会对file
命令的输出执行grep。 grep -q
表示不打印任何输出,但使用grep的退出代码查看是否找到了该字符串。如果您的系统未执行grep -q
,则可以尝试grep "regex" > /dev/null 2>&1
。
同样,file
命令的输出可能因系统而异,因此您必须验证这些命令是否适用于您的系统。另外,我正在检查可执行位。如果文件是二进制可执行文件,但可执行文件位未打开,我会说它不可执行。这可能不是你想要的。
答案 1 :(得分:10)
似乎没有人注意到-x
运算符与目录不同。
因此,要精确检查可执行文件,您可以使用
[[ -f SomeFile && -x SomeFile ]]
答案 2 :(得分:4)
似乎没有人注意到符号链接上的-x运算符。对常规文件(未归类为可执行文件)的符号链接(链)未通过测试。
答案 3 :(得分:1)
此处给出的解决方案在目录或符号链接(或两者)上都失败。在Linux上,您可以使用以下命令测试文件,目录和符号链接:
if [[ -f "$file" && -x $(realpath "$file") ]]; then .... fi
在OS X上,您应该能够使用自制软件安装coreutils并使用grealpath
。
isexec
函数为方便起见,您可以定义一个功能:
isexec() {
if [[ -f "$1" && -x $(realpath "$1") ]]; then
true;
else
false;
fi;
}
或者只是
isexec() { [[ -f "$1" && -x $(realpath "$1") ]]; }
然后你可以使用:
进行测试if `isexec "$file"`; then ... fi
答案 4 :(得分:0)
要测试文件本身是否在任何权限集(用户,组,其他)中都设置了ACL_EXECUTE
位,无论它位于何处,即e。即使在具有 noexec 选项的 tmpfs 上,也可以使用stat -c '%A'
获取权限字符串,然后检查其是否至少包含单个“ x”字母:>
if [[ "$(stat -c '%A' 'my_exec_file')" == *'x'* ]] ; then
echo 'Has executable permission for someone'
fi
可以对比较的右侧部分进行修改以适应更具体的情况,例如*x*x*x*
,以检查将各种文件放置在安装了< em> exec 选项。
答案 5 :(得分:0)
这可能不是很明显,但是需要一些时间来测试可执行文件以在没有外部shell进程的情况下适当地调用它:
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
在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
在Linux中:
> tkl_exec_inproc /bin/bash -c 'echo 123'
123
> tkl_exec_inproc ./myscript.sh
123
> echo $?
123
答案 6 :(得分:0)
首先你需要记住,在 Unix 和 Linux 中,一切都是一个文件,甚至是目录。一个文件要有作为命令执行的权限,需要满足三个条件:
所以这可以简单地完成:
[ -f "${file}" ] && [ -r "${file}" ] && [ -x "${file}" ]
如果您的文件是到常规文件的符号链接,则测试命令将对目标而不是链接名称进行操作。所以上面的命令区分文件是否可以用作命令。因此无需先将文件传递给 realpath
或 readlink
或任何这些变体。
如果该文件可以在当前操作系统上执行,那就是另一个问题了。上面的一些答案已经指出了一些可能性,所以这里不需要重复。