Lesson 17 / الدرس 17

Where a command comes from / من أين يأتي الأمر

You type php and something runs. Which something is decided by one variable, searched left to right — and that search explains almost every "wrong version" problem you will hit.

تكتب php فيعمل شيء. وأي شيء يقرره متغيّر واحد يُبحث فيه من اليسار لليمين — وذلك البحث يفسّر كل مشكلة "النسخة الخطأ" تقريبًا ستقابلها.

A command is usually a file somewhere on the disk. When you type a bare name with no path, the shell has to find that file, and it does so by walking through the directories listed in PATH in order, taking the first match and stopping. Not the newest, not the best — the first.

$ echo $PATH
/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin
 └──────┬──────┘ └──────┬─────┘ └──┬───┘
     searched        then this   then this ...
      first
One string, directories separated by colons, searched strictly left to right. The order is the entire mechanism: a php in the first directory wins over a php in the third, whatever their version numbers.

Asking which one you have

CommandAnswers
which phpThe path of the one that would run
type phpWhat kind of thing it is: file, built-in, alias or function
command -v phpThe same as which, but reliable in scripts
which -a phpEvery match on PATH, in search order
php --versionWhat that one actually is

which -a is the one that solves the mystery: it shows every candidate, so you can see the one that is winning and the one you wanted sitting behind it.

$ which -a php
/opt/homebrew/bin/php      ← 8.3, found first, so this is what runs
/usr/bin/php               ← 8.1, shipped with the system, never reached
Both are installed, both work, and only the first is ever used. Run the demonstration for the four kinds of thing a name can turn out to be — the answer is not always a file, which is why type tells you more than which.

Changing the order

To make a directory win, put it at the front: export PATH="/opt/php83/bin:$PATH". Read that carefully — the new directory comes first and the old value is appended after it, so nothing is lost. Putting it at the end instead means it is only reached when nothing earlier matched, which is usually not what you wanted.

Note also that the current directory is not on PATH, deliberately. To run a program sitting in front of you, you must write ./deploy.sh — the ./ is not decoration. If the current directory were searched, anyone who could put a file named ls into a directory you visit could have you run their program by accident.

Try it live / جرّب بنفسك

Preview / المعاينة

Check yourself / اختبر نفسك

1. Two versions of a program are installed. Which one runs?

2. Why must you type ./script.sh rather than script.sh?

3. What is wrong with export PATH="/opt/bin"?

Your task / مهمتك

Print your own PATH and take it apart: list the directories in search order and say what lives in each. Then pick a command you use often and investigate it with which -a and type — report whether more than one copy exists, which one wins, and why.

اطبع PATH الخاص بك وفككه: عدّد المجلدات بترتيب البحث وقل ما الذي يعيش في كل واحد. ثم اختر أمرًا تستخدمه كثيرًا وافحصه بـwhich -a وtype — وأبلغ هل توجد أكثر من نسخة، وأيها يفوز، ولماذا.

  • Your real PATH, split into its directories in order PATH الحقيقي مقسّمًا إلى مجلداته بالترتيب
  • What each directory is for ما وظيفة كل مجلد
  • One command investigated with which -a and type أمر واحد مفحوص بـwhich -a وtype
  • Which copy wins, and why أي نسخة تفوز، ولماذا
How do you want to submit? / كيف تريد التسليم؟