---
title: "أتقن فنون الـ Shell"
description: "إن كنتم مطوّرين، فغالبًا تقضون وقتًا طويلًا في سطر الأوامر. إليكم بعض النصائح والحيل التي تعلّمتها على مر السنين."
canonical: https://oozou.com/ar/blog/i-know-shell-fu-81
locale: ar
date: 2020-08-02
author: "OOZOU Team"
---

# أتقن فنون الـ Shell

> إن كنتم مطوّرين، فغالبًا تقضون وقتًا طويلًا في سطر الأوامر. إليكم بعض النصائح والحيل التي تعلّمتها على مر السنين.

Published: 2020-08-02 · Author: OOZOU Team (Engineering) · 6 min read

# أوامر أساسية يجب أن تعرفوها

إن أردتم عرض كل المجلدات والملفات في المجلد الحالي، فاستخدموا الأمر **_ls_**:

```shell
$ ls /var/log
=> system.log
=> shutdown_monitor.log
=> ...
```

في البرمجة، كثيرًا ما تكون لدينا ملفات إعداد مخفية. وتُسمى dotfiles لأنها تبدأ بنقطة، مثل **.**_file_** يمكنكم تعديل أمر العرض باستخدام الخيار **_\-a_** (all)، مثل **_ls -a_**، الذي يعرض كل الملفات بما فيها ملفات الإعداد المخفية:

```shell
$ ls -a
=> .git/
=> .ruby-version
=> .oozou
```

لنفترض الآن أنكم تريدون حذف مجلد يحتوي على ملفات. بدلًا من اللجوء إلى Finder، يمكنكم استخدام الأمر **_rm_**، لكنه لا يحذف إلا الملفات المفردة أو المجلدات الفارغة. وإن احتجتم إلى حذف المجلد بأكمله، فاستخدموا الخيار **_\-r_** (recursive)، مثل **_rm -r_**، الذي يحذف كل الملفات في المجلد إضافة إلى المجلد نفسه. ويمكنكم أيضًا استخدام تعبيرات wildcard لمطابقة ملفات محددة في المجلد. ربما تريدون حذف كل الملفات النصية مثلًا:

```
$ <em>rm -r dirname/*.txt
=> Deleted 10 files matching dirname/*.txt
language-shell</em>
```

أحيانًا ستجدون أن بعض الملفات محمية من الكتابة، فيُطلب منكم تأكيد رغبتكم فعلًا في حذفها. وإن كنتم تحذفون ملفات محمية من الكتابة بشكل متكرر، فقد يصبح إدخال _y_ لتأكيد الحذف مرة بعد مرة أمرًا مرهقًا. وللتغلب على ذلك، نمرّر الخيار **_\-f_** (force) لنطلب من أمر الحذف المضي قدمًا من دون سؤال:

```
$ <em>rm -rf dirname/write-protected.*.txt
=> Deleted 10 write protected files without bothering you for permission
language-shell</em>
```

# بعض اختصارات الـ Shell

هل حدث أن كتبتم أمرًا ونسيتم _sudo_؟ هل تعلمون أنكم تستطيعون استخدام **_!!_** لإعادة تشغيل آخر أمر؟ هذا مفيد جدًا لإعادة تشغيل الأوامر الفاشلة مع sudo:

```shell
$ rm -rf /important-directory
=> permission denied
$ sudo !!
=> I'm sorry, I didn't realize it was you, go right ahead
```

يمكنكم عرض سجل كل أوامركم بكتابة **_history_** في سطر الأوامر:

```
$ history
=> 1 ls /var/log
=> 2 ls -a
=> 3 <em>rm -r dirname/*.txt</em>
=> 4 <em>rm -rf dirname/write-protected.*.txt
</em>=> 5 rm -rf /important-directory
=> 6 sudo rm -rf /important-directory
```

ويمكنكم أيضًا استخدام **_!-n_** (حيث n رقم) لاستدعاء الأمر الذي استخدمتموه قبل n أوامر:

```shell
$ pwd
=> /Users/joe/foo
$ cd ~
$ !-2
=> /Users/joe
```

ويمكنكم كذلك استخدام **_!substring_** لاستدعاء آخر أمر يبدأ بهذا النص:

```shell
$ ffmpeg -i video.flv video.mpeg
=> video.flv not found
$ ls
=> thumbnail.png
$ cd ..
$ ls
=> thumbnails/ videos/
$ cd videos
$ !ffmpeg
=> converting video.flv to video.mpeg
```

ثم يمكننا فعل أشياء أكثر جرأة، مثل استبدال نص في الأمر السابق:

```shell
$ rm -r dir/foo/*.rb
=> removed all ruby files in dir/foo/
$ ^foo^bar
=> removed all ruby files in dir/bar/
```

# بعض حيل Rails التي أستخدمها كثيرًا

إضافة ملف إلى ._gitignore_ من دون فتح المحرر أمر بسيط، يكفي أن تدفعوه إليه. (ملاحظة: احذروا من استخدام > وإلا فستستبدلون محتوى الملف بالكامل، فنحن نريد >> لإلحاق النص):

```shell
$ "public/assets" >> .gitignore
=> appended "public/assets" to .gitignore
```

هل تحتاجون إلى إيجاد route في تطبيق Rails؟ تعرفون جزءًا من اسمه لكنكم لستم متأكدين من الـ route بالضبط. يمكنكم البحث عنه باستخدام **_grep_**، وذلك بتمرير مخرجات **_bin/rails routes_** إلى grep عبر pipe، ثم استخدام الجزء الذي تعرفونه لتضييق النتائج:

```shell
$ bin/rails routes | grep auth
=>      oauth_token POST  /api/v1/oauth/token(.:format)        doorkeeper/tokens#create
=>     oauth_revoke POST  /api/v1/oauth/revoke(.:format)       doorkeeper/tokens#revoke
=> oauth_introspect POST  /api/v1/oauth/introspect(.:format)   doorkeeper/tokens#introspect
```

احفظوا مخرجات script في ملف عبر **إعادة توجيه المخرجات**، كما فعلنا سابقًا عند إضافة public/assets إلى ._gitignore_. لكن هذه المرة سنستبدل محتوى الملف بالكامل:

```shell
$ ruby ./scripts/1_million_dollars.rb > ./log/1_million_dollars.txt
=> No output here
$ cat ./log/did_i_get_1_million_dollars.txt
=> Don't you think we should maybe ask for more than a million dollars?
=> A million dollars isn't exactly a lot of money these days.
=> Virtucon alone makes over 9 billion dollars a year!
```

أو إن أردتم **تسجيل مخرجات** **STDERR** في ملف خاص بها:

```shell
$ ruby ./scripts/raise_allota_errors.rb 2> ./log/allota_errors.text
=> STDOUT output here
$ cat ./log/allota_errors.text
=> STDERR output here
```

يمكنكم استخدام **_less_** لعرض ملف. وأثناء تشغيل less، استخدموا _/substring_ للبحث في الملف، أو السهمين _up_ و_down_ للتنقل فيه. يشبه less الأمر more كثيرًا لكنه أسرع، لأنه لا يحمّل الملف كاملًا في الذاكرة.

```shell
$ less ./log/production.log
```

ويمكنكم أيضًا استخدام **_tail_** لمراقبة "ذيل" الملف في الوقت الفعلي، وهذا مفيد لمتابعة الـ logs أثناء كتابتها. احرصوا على استخدام خيار "follow" للمراقبة في الوقت الفعلي، وإلا فلن تروا سوى الأسطر الأخيرة من الملف (وإن كنتم على جهاز يدوّر الـ logs، فيمكنكم استخدام -F لمواصلة مراقبة الملف حتى بعد إعادة إنشائه أثناء التدوير):

```shell
$ tail -f ./log/production.log
=> ...
=> ...
=> ...
```

# أوامر مفيدة أخرى

هل احتجتم يومًا إلى معرفة عدد الأسطر في ملف؟ يمكنكم استخدام **wc** (word-count) وتمرير الخيار **_\-l_** (lines) لعدّ الأسطر:

```shell
$ wc -l ./users_dump.csv
=> 1337
```

ويمكنكم أيضًا استخدامه لعدّ أسطر مخرجات أي أمر، مثل معرفة عدد الملفات في مجلد:

```shell
$ ls ./node_modules | wc -l
=> 9284728927498392847393
```

هل احتجتم يومًا إلى كتابة أمر طويل وشعرتم بالإحباط من تجربة التحرير في الـ terminal؟ افتحوا محرركم (EDITOR) وحرّروا الأمر فيه بالضغط على **_ctrl-x ctrl-e:_**

```shell
$ some-long command ops I spelled that thing wrong ctrl-x ctrl-e
#> *opens your EDITOR*
#< save and close your editor to re-enter shell
$ some-long command I spelled correctly now
```

ولكي يعمل ذلك، تحتاجون إلى إضافة **_export EDITOR=your_editor_** في ملف _.bashrc_ أو _.zshrc_. بعض المحررات تحتاج إلى وضع _wait_ للعودة إلى الـ terminal بعد التحرير. وإن كنتم تستخدمون MacVim، فستحتاجون إلى تمرير أمر يُنفَّذ بعد VimLeave كما فعلت هنا_:
_

```shell
export EDITOR='mvim -f -c "au VimLeave * !open -a iTerm"'
```

# أتقن فنون الـ Shell

أرني!
الـ terminal مذهل! منه بدأنا، وما زال من أقوى الأدوات في عملي اليومي. وهناك الكثير مما لم أذكره في هذا المقال أصلًا. أنصحكم بالقراءة أكثر إن أثار أي من هذا اهتمامكم. فالـ shell موجود منذ ظهور الحواسيب الحديثة، لذا تتوفر عنه كمية هائلة من المعلومات. وإن كنتم تعرفون أي حيل في الـ shell، فيسعدني أن أسمعها.

---

Contact OOZOU: hello@oozou.com · +66 2544 0000 · https://oozou.com/ar/contact

More for AI agents: https://oozou.com/llms.txt · every page has a markdown twin at its URL plus ".md"
