コマンド、システムコール、bash組み込みなどが何であるかをどうやって知ることができますか?

コマンド、システムコール、bash組み込みなどが何であるかをどうやって知ることができますか?

最近仲間が「何ですかman?」と聞きました。これについて学んだらBash CLIからアクセスできるすべてがコマンドではありません。、私は慎重に注文を要求しましたman

man manただインターフェイスと呼んでください。

NAME
       man - an interface to the on-line reference manuals

man実行可能ファイルがあります:

$ which man
/usr/bin/man
$ file /usr/bin/man
/usr/bin/man: ELF 64-bit LSB shared object

man実行可能ファイルを含むプログラムも同じですか?他の名詞は何ですかman?それを最もよく説明する名詞は何ですか?実際、私は一般的なケースに興味があります。決定できるものはthing on the cli任意ですman。これは単なる例です。

それでは、Bash CLIで利用可能なすべてを指す単語は何ですか?コマンド、エイリアス、システムコールなどを含む単語は何ですか?

答え1

POSIX用語でシェルにアクションを要求するすべてはコマンド:

特定のタスクを実行するようにシェルに指示する指示です。

だから

man man

(技術的に)コマンドです。

man

man道路ユーティリティ:

シェルコマンド言語の一部として提供される特別な組み込みユーティリティを除いて、特定のタスクまたは関連するタスクセットを実行するためにシェルから名前で呼び出すことができるプログラム。

(ここでは除外は重要ではありません。特定の属性を持つ特別な組み込みユーティリティ.)

指定されたコマンドが何であるかを調べるには、を使用しますtype。これにより、組み込みのコマンドなのか、プログラムなのかPATH(どこなのか)、エイリアスなどなのか(または不明なのか)わかります。

システムコールはシェルコマンドとして使用できません。

また、見ることができますコマンドですか、それともユーティリティですか?そして組み込みコマンドと非組み込みコマンドの違いは何ですか?

答え2

一番下から始まる:

システムコール

システムコールは、ユーザースペース操作がカーネルから特定のサービスを要求し、特権カーネルモードで実行される方法です。

プログラミング言語がCで、ジョブの現在のディレクトリを変更したい場合は、次のように挿入する必要があります。chdir()プログラムに指示を追加してください。

もちろん、これらのプログラムはすぐにはコマンドラインからアクセスできます。 vgコマンドラインにchdirを入力してもchdirシステムコールは呼び出されません。

利用可能なすべてのシステムコールのリストは、カーネルによって異なり、信頼できる唯一のソースだけでなく、カーネルソースディストリビューションinclude/linux/syscalls.hのヘッダファイルです。

指示する

CLIは実行中のジョブへのインターフェースです。あなたが入力するものは何でも呼び出されますガイドラインただ作業が何かを成し遂げるように指示することになっているからです。

注文する

入力した内容は、まずインタプリタを介して入力したトークンの語彙分析を行い、特定のシェルの場合は名前を認識できます。注文する(変数割り当てではないと理解されています)要求を実装するには別のプログラムを使用する必要があると偶然に決めました。次に、他のプログラムのバイナリを実行するサブプロセスをフォークします。

ただし、一部の特殊なケースでは、外部プロシージャ(単純な微積分など)を使用せずに要求を実行する方が簡単な場合があります。さらに重要なこと〜しなければならない要求を内部的に実行します。

組み込みコマンド

Active Directoryを変更する元の意図に戻り、ユーザーはよく知られているシェルコマンドを実行しますcd。ユーザーが本当に望むのは、シェルの現在のディレクトリを変更することです。また、chdirシステムコールは呼び出し元の現在の作業ディレクトリのみを変更するため、シェルは親プロセスを変更しない他のプロセスをフォークできません。シェルは内部的にchdirシステムコールを実行する必要があります。

yourshellnameシェル組み込みコマンドは、すべてのマニュアルページにリストされています。

ニックネーム

ニックネームは、すべてのユーザーが設定できる同義語に過ぎず、コマンドラインソルバーによって目的の文字列(シェルの正当なコマンドを表す必要がある)に変換されます。

alias現在アクティブなエイリアスのすべてのリストは、シェル組み込みコマンドを使用して取得できます。

答え3

コマンドを識別するのに役立つ小さなシェルスクリプトがあります。つまり、コマンドの種類が何であるか、パッケージを介してインストールされている場合、そのパッケージは何ですか。おそらくこの名前でwhat-about

#!/bin/bash

LANG=C
inversvid="\0033[7m"
resetvid="\0033[0m"

if [ $# -ne 1 ]
then
 echo "Usage: ${0##*/} <program-name>"
 echo "Will try to find corresponding package"
 echo "and tell what kind of program it is"
 exit 1
fi
command="$1"

str=;for ((i=1;i<=$(tput cols);i++)) do str="-$str";done
tmp="$command"
first=true
curdir="$(pwd)"
tmq=$(which "$command")
tdr="${tmq%/*}"
tex="${tmq##*/}"
if test -d "$tdr"; then cd "$tdr"; fi
#echo "cwd='$(pwd)' ################# d"

while $first || [ "${tmp:0:1}" == "l" ]
do
 first=false
 tmp=${tmp##*\ }
 tmq="$tmp"
 tmp=$(ls -l "$(which "$tmp")" 2>/dev/null)
 tdr="${tmq%/*}"
 tex="${tmq##*/}"
 if test -d "$tdr"; then cd "$tdr"; fi
# echo "cwd='$(pwd)' ################# d"
 if [ "$tmp" == "" ]
 then
  tmp=$(ls -l "$tex" 2>/dev/null)
  tmp=${tmp##*\ }
  if [ "$tmp" == "" ]
  then
   echo "$command is not in PATH"
#   package=$(bash -ic "$command -v 2>&1")
#   echo "package=$package XXXXX 0"
   bash -ic "alias '$command' > /dev/null 2>&1" > /dev/null 2>&1
   if [ $? -ne 0 ]
   then
    echo 'looking for package ...'
    package=$(bash -ic "$command -v 2>&1"| sed -e '0,/with:/d'| grep -v '^$')
   else
    echo 'alias, hence not looking for package'
   fi
#   echo "package=$package XXXXX 1"
   if [ "$package" != "" ]
   then
    echo "$str"
    echo "package: [to get command '$1']"
    echo -e "${inversvid}${package}${resetvid}"
   fi
   else
    echo "$tmp"
   fi
 else
  echo "$tmp"
 fi
done
tmp=${tmp##*\ }
if [ "$tmp" != "" ]
then
 echo "$str"
 program="$tex"
 program="$(pwd)/$tex"
 file "$program"
 if [ "$program" == "/usr/bin/snap" ]
 then
  echo "$str"
  echo "/usr/bin/snap run $command     # run $command "
  sprog=$(find /snap/"$command" -type f -iname "$command" \
   -exec file {} \; 2>/dev/null | sort | tail -n1)
  echo -e "${inversvid}file: $sprog$resetvid"
  echo "/usr/bin/snap list $command    # list $command"
  slist="$(/usr/bin/snap list "$command")"
  echo -e "${inversvid}$slist$resetvid"
 else
  package=$(dpkg -S "$program")
  if [ "$package" == "" ]
  then
   package=$(dpkg -S "$tex" | grep -e " /bin/$tex$" -e " /sbin/$tex$")
   if [ "$package" != "" ]
   then
    ls -l /bin /sbin
   fi
  fi
  if [ "$package" != "" ]
  then
   echo "$str"
   echo " package: /path/program  [for command '$1']"
   echo -e "${inversvid} $package ${resetvid}"
  fi
 fi
fi
echo "$str"
#alias=$(grep "alias $command=" "$HOME/.bashrc")
alias=$(bash -ic "alias '$command' 2>/dev/null"| grep "$command")
if [ "$alias" != "" ]
then
 echo "$alias"
fi
type=$(type "$command" 2>/dev/null)
if [ "$type" != "" ]
then
 echo "type: $type"
elif [ "$alias" == "" ]
then
 echo "type: $command: not found"
fi
cd "$curdir"

echo時には、別々にコンパイルされたプログラムとシェル組み込みコマンドであるforという2つのオプションがあります。別のプログラムへのフルパスを使用しない限り、組み込みシェルが優先的に使用され、

$ what-about echo
-rwxr-xr-x 1 root root 35000 jan 18  2018 /bin/echo
----------------------------------------------------------------------------------
/bin/echo: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=057373f1356c861e0ec5b52c72804c86c6842cd5, stripped
----------------------------------------------------------------------------------
 package: /path/program  [for command 'echo']
 coreutils: /bin/echo 
----------------------------------------------------------------------------------
type: echo is a shell builtin

rename時々私が使用したバージョンのように隠されている可能性があるプログラムにコマンドが接続されていることがあります。

$ what-about rename
lrwxrwxrwx 1 root root 24 maj 12  2018 /usr/bin/rename -> /etc/alternatives/rename
lrwxrwxrwx 1 root root 20 maj 12  2018 /etc/alternatives/rename -> /usr/bin/file-rename
-rwxr-xr-x 1 root root 3085 feb 20  2018 /usr/bin/file-rename
----------------------------------------------------------------------------------
/usr/bin/file-rename: Perl script text executable
----------------------------------------------------------------------------------
 package: /path/program  [for command 'rename']
 rename: /usr/bin/file-rename 
----------------------------------------------------------------------------------
type: rename is /usr/bin/rename

エラーを防ぐためにエイリアスがあり、エイリアスがrm優先されますPATH。バックスラッシュをプレフィックスとして使用して、\rmエイリアスをスキップしてプログラムを直接実行できます。 (エイリアスは特定のユーザーにのみ適用され、sudo同様のエイリアスが定義されていない限り、他のユーザーには適用されないことに注意してください。)

$ what-about rm
-rwxr-xr-x 1 root root 63704 jan 18  2018 /bin/rm
---------------------------------------------------------------------------
/bin/rm: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for
GNU/Linux 3.2.0, uildID[sha1]=864c9bbef111ce358b3452cf7ea457d292ba93f0,
stripped
---------------------------------------------------------------------------
 package: /path/program  [for command 'rm']
 coreutils: /bin/rm 
---------------------------------------------------------------------------
alias rm='rm -i'
type: rm is /bin/rm

関連情報