Bash 如何查看/bin/sh指向的内容

Bash 如何查看/bin/sh指向的内容,bash,shell,unix,aix,Bash,Shell,Unix,Aix,我在阅读关于/bin/sh和/bin/bash之间的区别的文章时,遇到了一个有趣的问题/答案: 我对我标题中提出的同一问题的答案发表了评论,他以最新的答案回答: >file -h /bin/sh >/bin/sh: executable (RISC System/6000) or object module >find -L /bin -samefile /bin/sh >find: bad option -samefile 如何找出/bin/sh在系统上指向的内容

我在阅读关于/bin/sh和/bin/bash之间的区别的文章时,遇到了一个有趣的问题/答案:

我对我标题中提出的同一问题的答案发表了评论,他以最新的答案回答:

>file -h /bin/sh
>/bin/sh: executable (RISC System/6000) or object module

>find -L /bin -samefile /bin/sh
>find: bad option -samefile
如何找出/bin/sh在系统上指向的内容

复杂的是/bin/sh可能是一个符号链接或硬链接 链接如果是符号链接,则可通过以下方式进行解析:

如果是硬链接, 试一试

我试过了,但遇到了麻烦,所以我想我会提出一个单独的问题

我从链接答案中得到的结果:

>file -h /bin/sh
>/bin/sh: executable (RISC System/6000) or object module

>find -L /bin -samefile /bin/sh
>find: bad option -samefile
我错过了什么? 我正在运行AIX:

>oslevel -s
7100-03-03-1415

正如您评论的答案所说,
-samefile
不是
find
的标准功能。也不是
-inum
,它根据显式给定的inode编号进行搜索。但是如果您的
查找
支持此功能,请使用它

POSIX
ls
支持打印inode编号的
-i
。如果
find
没有
-inum
,您所需要做的就是浏览所有可能的文件
/bin/sh
,可能是与

尽管在此之前,您可以检查文件是否有任何其他硬链接,
ls-l
需要显示链接数:

$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1029624 Nov  5 23:22 /bin/bash
           ^ here

当然,
/bin/sh
不需要链接到任何东西。它可能只是另一个程序。(或者甚至是其他文件的相同副本,尽管我认为这不太可能。)

如果需要通过编程测试它们是否相同,可以使用
stat
查询
/bin/sh
inode
,并与
/bin/bash
inode
进行比较

if [ $(stat -L -c %i /bin/sh) -eq $(stat -L -c %i /bin/bash) ]; then
    .....
fi
如果您只需要用眼睛查看它们是否相同,请运行
stat
命令,查看它们是否返回相同的
inode
编号

stat -L -c %i /bin/sh
stat -L -c %i /bin/bash

由于您只是在
bin
中搜索,因此您可以完全绕过
find
,只需检查
sh
bash
是否是指向同一文件的硬链接:

test /bin/sh -ef /bin/bash

这不如在所有可能的情况下运行
find
,可靠,但这是一个良好的开端。虽然不支持
-samefile
,但它支持
-exec
,可以将其与上面的命令组合以模拟相同的功能:

find -L /bin -exec test /bin/sh -ef '{}' ';'
检查GNUBash 我将以一种不同的方式回答您的问题,因为事实上,找出sh是否是gnubash(或者响应
--version
标志的其他东西)比追踪inode更简单还有一种边缘情况,外壳被重命名而不是链接,在这种情况下,映射链接并不能真正帮助您找到答案。

例如,要在macOS上查询/bin/sh:

$ /bin/sh --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation, Inc.
或者,您可以grep(或类似)字符串
bash
,以捕获退出状态。例如:

# Close stderr in case sh doesn't have a version flag.
if sh --version 2>&- | grep -qF bash; then
  echo "sh is bash"
else
  echo "sh isn't bash"
fi

当然,/bin/sh可能是bash或原始bourne shell之外的其他shell,但这超出了原始问题的范围。但是,许多shell(如ksh和tcsh)也支持版本标志,因此明智地使用
case
语句可以帮助您扩展测试,以准确确定哪个shell二进制文件/bin/sh是真正的。

您也可以执行
readlink-f/bin/sh
。对我来说,它指向
/bin/dash
我真的看不出这个练习的意义

if [ $(stat -L -c %i /bin/sh) -eq $(stat -L -c %i /bin/bash) ]; then
    .....
fi
/bin/sh
是一个POSIX外壳,
bash
对POSIX标准进行了扩展,
/bin/sh
不支持该扩展

如果您正在编写POSIX shell脚本,请使用
/bin/sh
。如果您正在编写
bash
shell脚本,请使用
bash

if [ $(stat -L -c %i /bin/sh) -eq $(stat -L -c %i /bin/bash) ]; then
    .....
fi
不要试图编写将使用
/bin/sh
执行的
bash
脚本,也不要试图通过编程尝试根据链接的
/bin/sh
(或当前解释器)确定当前shell的功能。相反,让脚本可执行并使用正确的
#-用于脚本的行。

您只需使用:

ls -l /bin/sh

运行
人工查找
。这是一个关于不同系统选项的非常有芬兰特色的程序。您的版本的
-samefile
如果存在,将使用不同的名称。看起来
/bin/sh
确实是系统上的可执行文件,而不是符号链接。请记住,它不一定“指向”其他shell可执行文件。显然,您的
find
实用程序不是gnu find实用程序,并且与该实用程序不兼容。这对于商业Unix变体来说并不奇怪。@arkascha。现在的问题不是它是一个可执行文件还是一个符号链接。问题是它是否是指向bash可执行文件的硬链接。AIX的
find
实用程序支持
-inum
。从
ls-i/bin/bash
获取
inode
,然后使用
find/bin-inum inode
查看是否会出现
/bin/sh
。或者只需比较ls-i/bin/sh/bin/bash的
inode
。硬链接是用于常规文件的文件系统指针结构。硬链接是对文件系统内部数据结构的引用。您无法区分常规文件和硬链接之间的区别,因为所有常规文件都是通过硬链接访问的。符号链接是包含路径的文件,该路径用于指向另一个文件。符号链接中的数据不指向文件系统的内部数据结构。这就是为什么符号链接可以指向单独的文件系统,而硬链接不能。在我看来,这是以编程方式进行测试时的最佳答案。答案只是一个简短的符号,我演示了如何将其插入find。这些年来,我从未注意到
-ef
操作数到
测试
。谢谢,蒂尔!嗨,我想这个问题有点复杂