【问题标题】:How to see what /bin/sh points to如何查看 /bin/sh 指向的内容
【发布时间】:2017-09-17 16:05:07
【问题描述】:

我在阅读 /bin/sh 和 /bin/bash 之间的区别时遇到了这个有趣的问题/答案:here

我对在我的标题中提出同样问题的答案发表了评论,他回复了更新的答案:

你如何知道 /bin/sh 在你的系统上指向什么?

复杂之处在于 /bin/sh 可能是符号链接或硬链接 关联。如果是符号链接,解决它的可移植方法是:

> % file -h /bin/sh
> /bin/sh: symbolic link to bash 

如果是硬链接, 试试

> % find -L /bin -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

我错过了什么? 我正在运行 AIX:

>oslevel -s
7100-03-03-1415

【问题讨论】:

  • 运行man find。这是一个对不同系统上的选项非常挑剔的程序。您的版本的 -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/bashinodes
  • 硬链接是用于常规文件的文件系统指针结构。硬链接是对文件系统内部数据结构的引用。您无法区分常规文件和硬链接,因为所有常规文件都是通过硬链接访问的。符号链接是包含路径的文件,该路径用于指向另一个文件。符号链接中的数据并不指向文件系统的内部数据结构。这就是为什么符号链接可以指向单独的文件系统,而硬链接不能。

标签: bash shell unix aix


【解决方案1】:

如果您需要以编程方式测试它们是否相同,您可以使用stat 查询/bin/shinode 并与/bin/bashinode 进行比较。

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

【讨论】:

    【解决方案2】:

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

    test /bin/sh -ef /bin/bash
    

    [ /bin/sh -ef /bin/bash ]
    

    这不如在所有可能性上运行find 可靠,但这是一个好的开始。虽然AIX find 不支持-samefile,但它支持-exec,可以结合上面的命令来模拟相同的功能:

    find -L /bin -exec test /bin/sh -ef '{}' ';'
    

    【讨论】:

    • 我认为以编程方式测试时的最佳答案。
    • 只是您答案的缩写符号,我展示了如何将其插入 find。
    • 这些年来,我从未注意到-eftest 的操作数。谢谢,直到!
    【解决方案3】:

    检查 GNU Bash

    我将以不同的方式回答你的问题,因为实际上找出 sh 是否是 GNU Bash(或其他响应 --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 是什么。

    【讨论】:

      【解决方案4】:

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

      POSIX ls 支持 -i,它会打印 inode 编号。如果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 不需要链接到任何东西。它可能只是另一个程序。 (或者甚至是其他一些文件的相同副本,尽管我认为这不太可能。)

      【讨论】:

        【解决方案5】:

        你可以使用:

        ls -l /bin/sh
        

        【讨论】:

        • 嗨,我认为这个问题比您提供的解决方案要复杂一些。考虑扩大或移除。
        • 这还不够复杂吗? OP 似乎正在运行一个奇怪的系统来发生这种情况,他并没有真正解释他的困惑是什么。这正是我一直在寻找的,如果没有别的,它回答了标题中的问题。
        【解决方案6】:

        你也可以readlink -f /bin/sh。对我来说,它指向/bin/dash

        【讨论】:

          【解决方案7】:

          我真的看不出这个练习的意义。

          /bin/sh 是 POSIX shell,bash 具有对 POSIX 标准的扩展,/bin/sh 不支持。

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

          不要尝试编写将使用/bin/sh 执行的bash 脚​​本,也不要尝试以编程方式尝试根据/bin/sh(或当前解释器)确定当前shell 的能力链接到。相反,使脚本可执行并为脚本使用正确的#!-line。

          【讨论】:

            猜你喜欢
            • 2016-04-02
            • 1970-01-01
            • 2016-09-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-04-08
            • 2020-11-23
            • 2022-10-25
            相关资源
            最近更新 更多