<?xml version="1.0"?>
<rss version="2.0"><channel><title>DevOps: Linux &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/page/6/?d=4</link><description>DevOps: Linux &#x644;&#x64A;&#x646;&#x643;&#x633;</description><language>ar</language><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x633;&#x62A;&#x62E;&#x62F;&#x645; &#x637;&#x631;&#x641;&#x64A;&#x629; &#x644;&#x64A;&#x646;&#x643;&#x633; &#x628;&#x627;&#x62D;&#x62A;&#x631;&#x627;&#x641;</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-%D8%B7%D8%B1%D9%81%D9%8A%D8%A9-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D8%A8%D8%A7%D8%AD%D8%AA%D8%B1%D8%A7%D9%81-r367/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_11/5a16e24ca3bf0_23-2(1).png.02a5212e1c5265aad7062dce1af56821.png" /></p>

<p>
	نحن نعرف أن الإنترنت يحفل بأوامر لينكس البسيطة التي رأيتها أو استخدمتها عشرات المرات من قبل، مثل <code>ls</code> لسرد محتوى مجلد أو <code>pwd</code> لمعرفة أين أنت الآن داخل النظام، و<code>cd</code> للتنقل بين المجلدات، وغير أولئك كلهم مما يشتهر من أوامر لينكس وينتشر في الإنترنت.<br>
	ولا شك أنك مللت من رؤيتها هنا وهناك في عشرات المواقع التي تعرض استخدامات الطرفية في لينكس، فأنت تريد تطوير مهاراتك في استخدام الطرفية لتنجز مهامًا بشكل أفضل، فإنك تعرف أن الطرفية مفيدة في أمور مثل إنهاء مهمة عالقة أو تستهلك الذاكرة، أو تحميل فيديو من يوتيوب بخيارات مختلفة بين الصوت والفيديو، أو الحصول على معلومات من ملف معين، أو حتى تصفح الإنترنت حين تريد الحفاظ على سعة باقة الإنترنت.<br>
	وفي هذا الجزء من المقال سنعرض بعض الأساليب التي تزيد من استفادتك من الطرفية وأوامرها.
</p>

<h2 id="كيفية-استخدام-أمر-cat-بشكل-أفضل">
	كيفية استخدام أمر cat بشكل أفضل
</h2>

<p>
	يحسب كثير من المبتدئين في لينكس أن <code>cat</code> يستخدم لعرض محتويات ملف في الطرفية، لكن هذا ليس صحيحًا. فقد يكون من المفيد عرض ملف .json في الطرفية، خاصة حين يكون لديك بيانات JSON من أجل طلب لـ rest <abbr title="Application Programming Interface | واجهة برمجية">api</abbr>. وعلى سبيل المثال، فهذا الأمر سيعرض محتويات ملف باستخدام أمر cat:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs avrasm"><span class="pln">cat  temperature</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">json</span></span></code></pre>

<p>
	وخرج هذا الأمر هو محتويات الملف:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
{
 "measured_at":"2015-12-25 21:55:57.188743+00:00",
 "sensor_id":"somekey",
 "temperature":14
}</pre>

<p>
	وسأستخدم ملف temperature.json من أجل طلب POST باستخدام أمر <code>curl</code>، لكن هذا لوقت آخر، دعنا نركّز الآن على أننا كلنا نعرف طريقة استخدام أمر cat بالطريقة السابقة من أجل عرض محتويات ملف ما، لكن هل جربت إنشاء ملف جديد باستخدامه من قبل؟<br><strong>1.</strong> طريقة إنشاء ملف جديد باستخدام cat هي هكذا:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs avrasm"><span class="pln">cat  </span><span class="pun">&gt;</span><span class="pln">newfile</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span></code></pre>

<p>
	<strong>2.</strong> ولنقل أني أريد نقل محتويات ملف قديم إلى آخر جديد، أستطيع هذا باستخدام cat أيضًا:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs avrasm"><span class="pln">cat  oldfile</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span><span class="pln">  </span><span class="pun">&gt;</span><span class="pln">newfile</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">txt</span></span></code></pre>

<p>
	سينسخ الأمر السابق كل محتويات oldfile، وينشئ ملفًا جديدًا باسم newfile، ويلصق المحتويات فيه، وإنني أفضّل هذه الطريقة على أمر <code>cp</code> في نسخ الملفات وعمل النسخ الاحتياطية إذ إنها أكثر عملية.<br><strong>3.</strong> ولدي أمر آخر أفعله باستخدام <code>cat</code>، وهو عرض أرقام الأسطر في الملف، حين أرغب في تحديد خطأ في سطر ما أو معرفة كم سطر في الملف
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs avrasm"><span class="pln">cat </span><span class="pun">-</span><span class="pln">n temperature</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">json</span></span></code></pre>

<p>
	وسيكون خرج هذا الأمر هو التالي:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs bash"><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">{</span><span class="pln">
 </span><span class="hljs-number"><span class="lit">2</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"measured_at"</span></span><span class="pun">:</span><span class="hljs-string"><span class="str">"2015-12-25 21:55:57.188743+00:00"</span></span><span class="pun">,</span><span class="pln">
 </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"sensor_id"</span></span><span class="pun">:</span><span class="hljs-string"><span class="str">"somekey"</span></span><span class="pun">,</span><span class="pln">
 </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"temperature"</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">14</span></span><span class="pln">
 </span><span class="hljs-number"><span class="lit">5</span></span><span class="pln"> </span><span class="pun">}</span></code></pre>

<p>
	<strong>4.</strong> ويمكننا عرض الملف بشكل معكوس من الأسفل إلى الأعلى باستخدام نفس الأمر معكوسًا، هكذا:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs avrasm"><span class="pln">tac temperature</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">json</span></span></code></pre>

<p>
	ويكون الخرج هكذا:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs css"><span class="pun">}</span><span class="pln">
 </span><span class="str">"</span><span class="hljs-tag"><span class="str">temperature</span></span><span class="str">"</span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">14</span></span><span class="pln">
 </span><span class="str">"</span><span class="hljs-tag"><span class="str">sensor_id</span></span><span class="str">"</span><span class="hljs-pseudo"><span class="pun">:</span><span class="str">"somekey"</span></span><span class="pun">,</span><span class="pln">
 </span><span class="str">"</span><span class="hljs-tag"><span class="str">measured_at</span></span><span class="str">"</span><span class="hljs-pseudo"><span class="pun">:</span><span class="str">"2015-12-25</span></span><span class="str"> 21</span><span class="hljs-pseudo"><span class="str">:55</span></span><span class="hljs-pseudo"><span class="str">:57</span></span><span class="hljs-class"><span class="str">.188743</span></span><span class="str">+00</span><span class="hljs-pseudo"><span class="str">:00"</span></span><span class="pun">,</span><span class="pln">
</span><span class="hljs-rules"><span class="pun">{</span></span></code></pre>

<h2 id="كيفية-استخدام-أمر-ls-بشكل-عملي">
	كيفية استخدام أمر ls بشكل عملي
</h2>

<p>
	<strong>1.</strong> قد يبدو أمر <code>ls</code> أمرًا بسيطًا لمعظم مستخدمي لينكس، لكن ذلك الأمر يخفي كثيرًا من العملية والقوة، فيمكننا أن نعرف هل يوجد ملف باسم معين داخل مجلد ما، دون أن نبحث يدويًا عن الملف، من خلال استخدام أنبوب-pipe:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs 1c"><span class="pln">ls </span><span class="hljs-string"><span class="pun">|</span><span class="pln"> grep somefile</span></span></code></pre>

<p>
	هذا الأمر السابق هو دمج بين أمرين، وهما <code>ls</code> الذي نستخدمه لعرض محتوى المجلد و<code>grep</code> الذي يأتي لنا بنص معين إن كان موجودًا، لذا فإن <code>ls</code> في الأمر السابق سيعرض محتويات المجلد، لكنه سيمررها إلى <code>grep</code> عبر الأنبوب “|” فيبحث الأخير عن الملف الذي نريده ويخبرنا أموجود هو أم لا. ويكون الخرج هو الملف الذي نريده فقط إن كان موجودًا.<br><strong>2.</strong> إن كنت أريد عرض المحتويات المخفية داخل المجلد فأستخدمه مع -a
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs bash"><span class="pln">ls </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">a</span></span></code></pre>

<p>
	لاحظ أن الملفات التي يبدأ اسمها بنقطة(.) يعتبرها لينكس ملفات مخفية، وهذا الأمر بالأعلى يعرضها.<br><strong>3.</strong> إن كنت أرغب في عرض الملفات حسب آخر تاريخ تعديل لها نضيف لاحقة -t
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs mel"><span class="hljs-keyword"><span class="pln">ls</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">t</span></code></pre>

<p>
	<strong>4.</strong> ويمكن أن نضيف وظيفة أخرى إليه، وهي جعل الخرج أكثر قابلية للقراءة، بإضافة حرف l إليه كي يظهر لنا صلاحيات الملفات والحجم وغير ذلك، هكذا:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs bash"><span class="pln">ls </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">lt</span></span></code></pre>

<p>
	<strong>5.</strong> ولتحديد نوع المحتويات داخل مجلد ما، نضيف لاحقة -F إلى أمر <code>ls</code>، كي يظهر لنا ما إذا كان هذا مجلد فرعي أو ملف تنفيذي أو غير ذلك، هكذا:<br>
	سنستخدم الأمر العادي <code>ls</code> لإظهار محتويات مجلد ما، فيخرج لنا هذا المحتوى:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs rsl"><span class="hljs-keyword"><span class="pln">normal</span></span><span class="pun">.</span><span class="pln">txt unixmen</span></code></pre>

<p>
	أما حين نكتب <code>ls -F</code>، يكون الخرج هكذا:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs rsl"><span class="hljs-keyword"><span class="pln">normal</span></span><span class="pun">.</span><span class="pln">txt unixmen</span><span class="pun">/</span></code></pre>

<p>
	وهنا يمكننا رؤية أن unixmen هو مجلد وليس ملف، بما أن لينكس يلحق أسماء المجلدات بـ /.
</p>

<h2 id="كيف-أعرف-إن-كان-اتصالي-بالإنترنت-سليما">
	كيف أعرف إن كان اتصالي بالإنترنت سليمًا؟
</h2>

<p>
	تحدث هذه الحالة حين تريد زيارة موقع ولا تستطيع، وتتحير هل المشكلة منك ومن إعدادات الشبكة أم من الموقع نفسه، والحل هو أمر <code>ping</code>:<br>
	مثال على جوجل:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs avrasm"><span class="hljs-built_in"><span class="pln">ping</span></span><span class="pln"> www</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">google</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">com</span></span></code></pre>

<p>
	وإن أخرج لك الأمر ردًا فهذا يعني أن المشكلة ليست من عندك.
</p>

<h2 id="كيف-أعدل-الملفات-من-الطرفية">
	كيف أعدّل الملفات من الطرفية؟
</h2>

<p>
	لعلك سمعت بمحرر ViM الشهير، وهو محرر يعمل من الطرفية، ويفيدني جدًا حين أريد كتابة بعض بياناتjson لطلب POST، يمكنك تثبيته بهذا الأمر (إن كنت تستخدم أوبنتو):
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> apt</span><span class="pun">-</span><span class="kwd">get</span><span class="pln"> install vim</span></code></pre>

<p>
	ثم نفتح به ملفًا لتعديله، نكتب <code>vim</code> ثم اسم الملف:
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs "><span class="pln">vim file2editinhere</span></code></pre>

<p>
	ولدخول وضع التعديل في الملف نضغط حرف i، ثم نكتب ونعدّل كما نشاء، ثم نضغط Esc للخروج من وضع التعديل، ونكتب نقطتين فوق بعضهما كهذه (:)ثم wq، كل ذلك دون مسافات، لنحفظ الملف ونغلقه،
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs ruby"><span class="hljs-symbol"><span class="pun">:</span><span class="pln">wq</span></span></code></pre>

<p>
	أما إن أردت الحفظ فقط، فنكتب : ثم w.
</p>

<pre class="ipsCode" id="ips_uid_4127_7">
<code class="hljs ruby"><span class="hljs-symbol"><span class="pun">:</span><span class="pln">w</span></span></code></pre>

<p>
	ترجمة -بتصرف- لمقال <a href="https://www.unixmen.com/use-linux-terminal-like-real-pro-first-part/" rel="external nofollow">How to use the linux terminal like a bro, First part</a> لصاحبه SureSwift Content
</p>
]]></description><guid isPermaLink="false">367</guid><pubDate>Thu, 23 Nov 2017 15:01:12 +0000</pubDate></item><item><title>&#x62A;&#x62D;&#x644;&#x64A;&#x644; &#x627;&#x644;&#x634;&#x628;&#x643;&#x627;&#x62A;: &#x643;&#x64A;&#x641;&#x64A;&#x629; &#x62A;&#x62B;&#x628;&#x64A;&#x62A; &#x625;&#x637;&#x627;&#x631; &#x627;&#x644;&#x645;&#x631;&#x627;&#x642;&#x628;&#x629; &#x627;&#x644;&#x634;&#x628;&#x643;&#x64A;&#x629; Bro &#x639;&#x644;&#x649; &#x62E;&#x627;&#x62F;&#x645; &#x623;&#x648;&#x628;&#x646;&#x62A;&#x648; 16.04</title><link>https://academy.hsoub.com/devops/linux/%D8%AA%D8%AD%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA-%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%A7%D9%84%D9%85%D8%B1%D8%A7%D9%82%D8%A8%D8%A9-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D9%8A%D8%A9-bro-%D8%B9%D9%84%D9%89-%D8%AE%D8%A7%D8%AF%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1604-r366/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_11/21-2.png.4ba67a033fd17fc1bfacb4159f3803b8.png" /></p>

<h2 id="مقدمة-إطار-التحليل-الشبكي-bro">
	مقدمة: إطار التحليل الشبكي Bro
</h2>

<p>
	هو إطار عمل مفتوح المصدر لتحليل الشبكات يركز على مراقبة أمانها، وهو نتاج خمس عشرة سنة من البحث واستخدمته جامعات كثيرة ومعامل بحثية ومراكز حواسيب خارقة وعدد من مجتمعات العلوم المفتوحة-Open Science. وقد بدأ تطويره بشكل أساسي في المعهد الدولي لعلوم الحاسوب في بيركلي والمركز الوطني لتطبيقات الحواسيب الخارقة في أوربانا-شامبين في إيلينوي.<br>
	وتتلخص مزايا Bro فيما يلي:
</p>

<ul>
<li>
		سياسات مراقبة خاصة بكل موقع، إذ تسمح لغة Bro النصية-scripting language بذلك
	</li>
	<li>
		استهداف الشبكات عالية الأداء.
	</li>
	<li>
		محللات للعديد من البروتوكولات، مما يسمح بالتحليل الدلالي عالي المستوى-High Level Semantic Analysis حتى على مستوى التطبيق.
	</li>
	<li>
		جمع إحصائيات شاملة على مستوى التطبيق للشبكة التي يراقبها.
	</li>
	<li>
		تسجّيل كل شيء يراقبه، ويوفّر أرشيفًا عالي المستوى لنشاط الشبكة.
	</li>
</ul>
<h2 id="متطلبات-bro-للعمل-على-الخادم">
	متطلبات Bro للعمل على الخادم
</h2>

<p>
	يحتاج Bro إلى الاعتماديات-Dependencies التالية:
</p>

<ul>
<li>
		<a href="http://www.tcpdump.org/" rel="external nofollow">Libpcap</a>
	</li>
	<li>
		<a href="http://www.openssl.org/" rel="external nofollow">مكتبات Open <abbr title="Secure Socket Layer | طبقة المنافذ الآمنة">SSL</abbr></a>
	</li>
	<li>
		مكتبة BIND8
	</li>
	<li>
		Libz
	</li>
	<li>
		Bash (نحتاجها من أجل BroControl)
	</li>
	<li>
		Python إصدار 2.6 أو أحدث (من أجل BroControl)
	</li>
</ul>
<p>
	كما يتطلب بناؤه من المصدر ما يلي:
</p>

<ul>
<li>
		CMake 2.8 أو أحدث
	</li>
	<li>
		Make
	</li>
	<li>
		GCC 4.8 فأحدث، أو Clang 3.3 فأحدث
	</li>
	<li>
		SWIG
	</li>
	<li>
		GNU Bison
	</li>
	<li>
		Flex
	</li>
	<li>
		Libpcap headers
	</li>
	<li>
		OpenSSL headers
	</li>
	<li>
		zlib headers
	</li>
</ul>
<h2 id="بدء-العمل">
	بدء العمل
</h2>

<p>
	ثبّت الاعتماديات المطلوبة بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
# apt-get install cmake make gcc g++ flex bison libpcap-dev libssl-dev python-dev swig zlib1g-dev</pre>

<h3 id="تثبيت-قاعدة-بيانات-geoip-من-أجل-موقع-ip-الجغرافي">
	تثبيت قاعدة بيانات GeoIP من أجل موقع IP الجغرافي
</h3>

<p>
	يعتمد Bro على GeoIP لتحديد الموقع الجغرافي للعنوان، فثبّت إصدارات IPv4، وIPv6 عبر هذه الأوامر:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs avrasm"><span class="pln">$ wget http</span><span class="pun">:</span><span class="com">//geolite</span><span class="hljs-preprocessor"><span class="com">.maxmind</span></span><span class="hljs-preprocessor"><span class="com">.com</span></span><span class="com">/download/geoip/database/GeoLiteCity</span><span class="hljs-preprocessor"><span class="com">.dat</span></span><span class="hljs-preprocessor"><span class="com">.gz</span></span></code></pre>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs ruby"><span class="hljs-variable"><span class="pln">$ </span></span><span class="pln">wget </span><span class="hljs-symbol"><span class="pln">http</span><span class="pun">:</span></span><span class="com">/</span><span class="hljs-regexp"><span class="com">/geolite.maxmind.com/download</span></span><span class="hljs-regexp"><span class="com">/geoip/database</span></span><span class="hljs-regexp"><span class="com">/GeoLiteCityv6-beta/</span></span><span class="hljs-constant"><span class="com">GeoLiteCityv6</span></span><span class="com">.dat.gz</span></code></pre>

<p>
	فُكّ ضغط تلك الأرشيفات التي حملناها:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs avrasm"><span class="pln">$ gzip </span><span class="pun">-</span><span class="pln">d </span><span class="typ">GeoLiteCity</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">dat</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">gz</span></span><span class="pln">
$ gzip </span><span class="pun">-</span><span class="pln">d </span><span class="typ">GeoLiteCityv6</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">dat</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">gz</span></span></code></pre>

<p>
	انقل الملفات التي فككناها إلى مجلد GeoIP:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs vala"><span class="hljs-preprocessor"><span class="com"># mvGeoLiteCity.dat /usr/share/GeoIP/GeoIPCity.dat</span></span><span class="pln">
</span><span class="hljs-preprocessor"><span class="com"># mv GeoLiteCityv6.dat /usr/share/GeoIP/GeoIPCityv6.dat</span></span></code></pre>

<h2 id="بناء-bro-من-المصدر">
	بناء Bro من المصدر
</h2>

<p>
	سنحصل على احدث إصدار من مستودعات git (<a href="https://academy.hsoub.com/devops/deployment/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-%D9%88%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-git-%D9%88gitolite-%D9%84%D9%84%D8%AA%D8%AD%D9%83%D9%85-%D9%81%D9%8A-%D8%A7%D9%84%D8%A5%D8%B5%D8%AF%D8%A7%D8%B1%D8%A7%D8%AA-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-r200/" rel="">اقرأ هذا المقال لتثبيتgit وإعداده إن لم يكن مثبتًا لديك</a>)، عبر الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs ruby"><span class="hljs-variable"><span class="pln">$ </span></span><span class="pln">git clone </span><span class="pun">--</span><span class="pln">recursive </span><span class="hljs-symbol"><span class="pln">git</span><span class="pun">:</span></span><span class="com">/</span><span class="hljs-regexp"><span class="com">/git.bro.org/bro</span></span></code></pre>

<p>
	نذهب إلى هذا المجلد المنسوخ-cloned directory، ونبني bro بهذه الأوامر:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs ruby"><span class="hljs-variable"><span class="pln">$ </span></span><span class="pln">cd bro
</span><span class="hljs-variable"><span class="pln">$ </span></span><span class="pun">./</span><span class="pln">configure
</span><span class="hljs-variable"><span class="pln">$ </span></span><span class="pln">make</span></code></pre>

<p>
	سيستغرق أمر make بعض الوقت للبناء، ويتوقف هذا الوقت على قوة الخادم نفسه. ويمكن تنفيذ شفرة configure النصية مع بعض المعاملات-arguments لتحديد أي الاعتماديات تريد بناءها، خاصة خيارات (–with-*)
</p>

<h2 id="تثبيت-bro">
	تثبيت Bro
</h2>

<p>
	داخل مجلد bro سابق الذكر، نفذ الأمر التالي، حيث سيكون مجلد التثبيت هو usr/local/bro/
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs vala"><span class="hljs-preprocessor"><span class="com"># make install</span></span></code></pre>

<h3 id="تهيئة-وإعداد-bro">
	تهيئة وإعداد Bro
</h3>

<p>
	تقع ملفات تهيئة Bro وضبطه في مجلد etc، في مسار usr/local/bro/etc/، وستجد ثلاثة ملفات:
</p>

<ul>
<li>
		node.cfg، يستخدم لتحديد أي عقدة-node أو مجموعة عُقّد سيراقبها (العقدة في الشبكات هي جهاز يتلقى/يشكّل/يحوّل المعلومات الواردة عبره).
	</li>
	<li>
		broctl.cfg، ملف تهيئة BroControl.
	</li>
	<li>
		networks.cgf، يحتوي قائمة بالشبكات في ترميز التوجيه غير الفئوي-<a href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation" rel="external nofollow">CIDR Notation</a>.
	</li>
</ul>
<h3 id="ضبط-إعدادات-البريد">
	ضبط إعدادات البريد
</h3>

<p>
	افتح ملف broctl.cfg، حيث تستبدل $EDITOR في الأمر التالي بالمحرر النصي الذي تفضله:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs vala"><span class="hljs-preprocessor"><span class="com"># $EDITOR /usr/local/bro/etc/broctl.cfg</span></span></code></pre>

<p>
	ابحث في الملف عن قسم Mail Options، وعدل سطر MailTo كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs oxygene"><span class="com"># Recipient address </span><span class="hljs-keyword"><span class="com">for</span></span><span class="com"> emails sent </span><span class="hljs-keyword"><span class="com">out</span></span><span class="com"> </span><span class="hljs-keyword"><span class="com">by</span></span><span class="com"> Bro </span><span class="hljs-keyword"><span class="com">and</span></span><span class="com"> BroControl</span><span class="pln">
</span><span class="typ">MailTo</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> admin@example</span><span class="pun">.</span><span class="pln">com</span></code></pre>

<p>
	استبدل عنوان البريد بالعنوان الذي تريد، ثم احفظ الملف وأغلقه. لديك الكثير من الخيارات هنا، لكن الخيارات الافتراضية جيدة ولا تحتاج تعديلات.
</p>

<h3 id="اختيار-العقد-التي-ستراقب">
	اختيار العُقَد التي ستُراقَب
</h3>

<p>
	إن Bro مجهز افتراضيًا ليعمل في الوضع المستقل-Standalone، وهو ما نشرحه في هذا المقال، لذا لن تحتاج إلى تغيير الكثير، لكن سننظر على أي حال في ملف node.cfg:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs vala"><span class="hljs-preprocessor"><span class="com"># $EDITOR /usr/local/bro/etc/node.cfg</span></span></code></pre>

<p>
	يجب أن ترى شيئًا كهذا في قسم [bro]:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs ini"><span class="hljs-title"><span class="pun">[</span><span class="pln">bro</span><span class="pun">]</span></span><span class="pln">
</span><span class="hljs-setting"><span class="pln">type</span><span class="pun">=</span><span class="hljs-value"><span class="pln">standalone</span></span></span><span class="pln">
</span><span class="hljs-setting"><span class="pln">host</span><span class="pun">=</span><span class="hljs-value"><span class="pln">localhost</span></span></span><span class="pln">
</span><span class="hljs-setting"><span class="kwd">interface</span><span class="pun">=</span><span class="hljs-value"><span class="pln">eth0</span></span></span></code></pre>

<p>
	تأكد أن تكون الواجهة-interface مطابقة لواجهة خادم أوبنتو 16.04، ثم احفظ الملف وأغلقه.
</p>

<h2 id="ضبط-شبكات-العقدة-nodes-networks">
	ضبط شبكات العقدة-Node’s Networks
</h2>

<p>
	آخر ملف سنعدّل فيه هو network.cfg، افتحه باستخدام المحرر النصي الذي تفضله:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs vala"><span class="hljs-preprocessor"><span class="com"># $EDITOR /usr/local/bro/etc/networks.cfg</span></span></code></pre>

<p>
	يجب أن ترى المحتوى التالي:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs vbscript"><span class="com"># List of local networks </span><span class="hljs-keyword"><span class="com">in</span></span><span class="com"> CIDR notation, optionally followed by a</span><span class="pln">
</span><span class="com"># descriptive tag.</span><span class="pln">
</span><span class="com"># </span><span class="hljs-keyword"><span class="com">For</span></span><span class="com"> example, </span><span class="hljs-string"><span class="com">"10.0.0.0/8"</span></span><span class="com"> </span><span class="hljs-keyword"><span class="com">or</span></span><span class="com"> </span><span class="hljs-string"><span class="com">"fe80::/64"</span></span><span class="com"> are valid prefixes.</span><span class="pln">

</span><span class="hljs-number"><span class="lit">10.0</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="hljs-number"><span class="lit">.0</span></span><span class="pun">/</span><span class="hljs-number"><span class="lit">8</span></span><span class="pln">          </span><span class="hljs-keyword"><span class="typ">Private</span></span><span class="pln"> IP </span><span class="hljs-built_in"><span class="pln">space</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">172.16</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="hljs-number"><span class="lit">.0</span></span><span class="pun">/</span><span class="hljs-number"><span class="lit">12</span></span><span class="pln">       </span><span class="hljs-keyword"><span class="typ">Private</span></span><span class="pln"> IP </span><span class="hljs-built_in"><span class="pln">space</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">192.168</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="hljs-number"><span class="lit">.0</span></span><span class="pun">/</span><span class="hljs-number"><span class="lit">16</span></span><span class="pln">      </span><span class="hljs-keyword"><span class="typ">Private</span></span><span class="pln"> IP </span><span class="hljs-built_in"><span class="pln">space</span></span></code></pre>

<p>
	احذف المدخلات الثلاثة (التي هي أمثلة فقط لكيفية استخدام الملف)، وأدخل مساحةIP العامة والخاصة للخادم الخاص بك، على هذه الهيئة:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs avrasm"><span class="hljs-built_in"><span class="pln">X</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">X</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">X</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">X</span></span><span class="pun">/</span><span class="hljs-built_in"><span class="pln">X</span></span><span class="pln">        </span><span class="pun">مساحة</span><span class="pln"> IP </span><span class="pun">العامة</span><span class="pln">
</span><span class="hljs-built_in"><span class="pln">X</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">X</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">X</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">X</span></span><span class="pun">/</span><span class="hljs-built_in"><span class="pln">X</span></span><span class="pln">        </span><span class="pun">مساحة</span><span class="pln"> IP </span><span class="pun">الخاصة</span></code></pre>

<p>
	احفظ الملف وأغلقه.
</p>

<h2 id="إدارة-تثبيت-bro-باستخدام-brocontrol">
	إدارة تثبيت Bro باستخدام BroControl
</h2>

<p>
	تحتاج إلى استخدام BroControl من أجل إدارة Bro، وهو يأتي في صورة صَدفة تفاعلية-interactive shell وأداة سطر أوامر، افتح الصدفة بالآتي:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs vala"><span class="hljs-preprocessor"><span class="com"># /usr/local/bro/bin/broctl</span></span></code></pre>

<p>
	ولتستخدمها كأداة سطر أوامر، أضف معاملًا-argument إلى الأمر السابق، مثال:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs vala"><span class="hljs-preprocessor"><span class="com"># /usr/local/bro/bin/broctl status</span></span></code></pre>

<p>
	سيتحقق هذا الأمر من حالة Bro بإخراج نتيجة كهذه:
</p>

<pre class="ipsCode" id="ips_uid_3794_7">
<code class="hljs css"><span class="hljs-tag"><span class="typ">Name</span></span><span class="pln">         </span><span class="hljs-tag"><span class="typ">Type</span></span><span class="pln">       </span><span class="hljs-tag"><span class="typ">Host</span></span><span class="pln">          </span><span class="hljs-tag"><span class="typ">Status</span></span><span class="pln">    </span><span class="hljs-tag"><span class="typ"><abbr title="Process IDentifier | معرّف العملية أو البرنامج">Pid</abbr></span></span><span class="pln">    </span><span class="hljs-tag"><span class="typ">Started</span></span><span class="pln">
</span><span class="hljs-tag"><span class="pln">bro</span></span><span class="pln">          </span><span class="hljs-tag"><span class="pln">standalone</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">localhost</span></span><span class="pln">     </span><span class="hljs-tag"><span class="pln">running</span></span><span class="pln">   </span><span class="lit">6807</span><span class="pln">   </span><span class="lit">20</span><span class="pln"> </span><span class="hljs-tag"><span class="typ">Jul</span></span><span class="pln"> </span><span class="lit">12</span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">30</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">50</span></span></code></pre>

<h2 id="خاتمة">
	خاتمة
</h2>

<p>
	ما شرحناه في هذا المقال يلخص دليل تثبيت Bro، وقد استخدمنا طريقة التثبيت من المصدر لأنها أكفأ طريقة ممكنة للحصول على آخر إصدار متوفر، لكن اعلم أن أداة تحليل الشبكات هذه يمكن تحميلها أيضًا في صورة ملف ثنائي/تنفيذي إن لم ترغب ببنائها من الصفر.
</p>

<p>
	ترجمة -بتصرف- لمقال <a href="https://www.unixmen.com/how-to-install-bro-ubuntu-1604/" rel="external nofollow">Network Analysis: How To Install Bro On Ubuntu 16.04</a> لصاحبه Giuseppe Molica
</p>

<p>
	حقوق الصورة البارزة محفوظة لـ <a href="https://www.freepik.com/free-vector/infographic-analytics-illustration_1217965.htm" rel="external nofollow">Freepik</a>
</p>
]]></description><guid isPermaLink="false">366</guid><pubDate>Tue, 21 Nov 2017 12:15:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x62B;&#x628;&#x651;&#x62A; &#x628;&#x64A;&#x626;&#x629; &#x62A;&#x637;&#x648;&#x64A;&#x631; Go &#x639;&#x644;&#x649; &#x623;&#x648;&#x628;&#x648;&#x646;&#x62A;&#x648; 16.04</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%AB%D8%A8%D9%91%D8%AA-%D8%A8%D9%8A%D8%A6%D8%A9-%D8%AA%D8%B7%D9%88%D9%8A%D8%B1-go-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1604-r362/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_11/07.png.83f210b8de23e96737c83d34ff2c0d53.png" /></p>

<p>
	تزداد شعبية Go، وهي لغة برمجة حديثة تطوّرها شركة Google، تزداد كثيرا في التطبيقات والشركات؛ كما توفّر مجموعة متناسقة من المكتبات البرمجية. يشرح هذا الدرس خطوات تثبيت الإصدار 1.8 (الإصدار المستقر الأحدث حتى الآن) على توزيعة لينكس أوبونتو 16.04. سننفّذ في الخطوة الأخيرة من هذا الدرس تطبيق “أهلا بالعالم” صغيرا للتأكد من تثبيت مصرّف اللغة Compiler وعمله.
</p>

<h2 id="المتطلبات">
	المتطلّبات
</h2>

<p>
	يفترض هذا الدرس توفّر نظام أوبونتو 16.04 معدًّا للعمل مع مستخدم إداري غير المستخدم الجذر بالطريقة التي يشرحها <a href="https://academy.hsoub.com/devops/servers/%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A7%D9%84%D8%A7%D8%A8%D8%AA%D8%AF%D8%A7%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r4/" rel="">الإعداد الابتدائي لخادوم أوبونتو</a>.
</p>

<h2 id="الخطوة-الأولى-تثبيت-go">
	الخطوة الأولى: تثبيت Go
</h2>

<p>
	نبدأ بتثبيت Go على الخادوم. اتّصل - إن دعت الحاجة لذلك - بالخادوم عن طريق <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> sammy@your_server_ip</pre>

<p>
	اذهب إلى <a href="https://golang.org/dl/" rel="external nofollow">صفحة التنزيلات</a> على الموقع الرسمي لـGo واعثُر على رابط الملف المضغوط لآخر إصدار مستقر، مع قيمة تجزئة SHA256 الخاصة به.
</p>

<p>
	تأكد من أنك في المجلّد الشخصي للمستخدم ثم نزّل الإصدار انطلاقا من الرابط الذي تحصّلت عليه في الفقرة الماضية:
</p>

<pre class="ipsCode" id="ips_uid_7072_8">
cd ~
curl -O https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz</pre>

<p>
	استخدم الأمر <code>sha256sum</code> للتحقّق من الملف المضغوط:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs avrasm"><span class="pln">sha256sum go1</span><span class="hljs-number"><span class="pun">.</span><span class="lit">8</span></span><span class="hljs-number"><span class="lit">.3</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">linux</span></span><span class="pun">-</span><span class="pln">amd64</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">tar</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">gz</span></span></code></pre>

<p>
	مثال على المُخرجات:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs avrasm"><span class="hljs-number"><span class="lit">1862</span></span><span class="lit">f4c3d3907e59b04a757cfda0ea7aa9ef39274af99a784f5be843c80c6772</span><span class="pln">  go1</span><span class="hljs-number"><span class="pun">.</span><span class="lit">8</span></span><span class="hljs-number"><span class="lit">.3</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">linux</span></span><span class="pun">-</span><span class="pln">amd64</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">tar</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">gz</span></span></code></pre>

<p>
	ستحصُل على قيمة تجزئة Hash مثل تلك الموجودة في المُخرجات السابقة. تأكد من أنها توافق قيمة التجزئة الخاصة بالملف التي تحصّلت عليها من صفحة التنزيلات.
</p>

<p>
	سنستخدم الآن <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%A3%D9%85%D8%B1-tar-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r243/" rel="">الأمر <code>tar</code></a> لفك ضغط الملف. يطلُب الخيار <code>x</code> استخراج محتوى الملف المضغوط، يُظهر الخيار <code>v</code> مخرجات مفصَّلة ويحدّد الخيار <code>f</code> أننا سنمرّر للأمر <code>tar</code> اسم الملف المضغوط:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs avrasm"><span class="pln">tar xvf go1</span><span class="hljs-number"><span class="pun">.</span><span class="lit">6</span></span><span class="hljs-preprocessor"><span class="lit">.linux</span></span><span class="pun">-</span><span class="pln">amd64</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">tar</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">gz</span></span></code></pre>

<p>
	ستحصُل الآن على مجلّد باسم <code>go</code> في المجلّد الشخصي للمستخدم.
</p>

<p>
	نفّذ الأمرين التاليين ل<a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A8%D8%A7%D8%AF%D8%A6-%D8%A3%D8%B0%D9%88%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-file-permissions-%D8%B9%D9%84%D9%89-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r242/#%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D9%85%D9%84%D9%83%D9%8A%D8%A9-%D9%85%D9%84%D9%81" rel="">تعديل ملكية</a> المجلّد <code>go</code> ثم <a href="https://academy.hsoub.com/devops/linux/%D8%A3%D9%84%D9%81-%D8%A8%D8%A7%D8%A1-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r61/" rel="">نقله إلى المسار</a> <code>usr/local/</code> :
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> chown </span><span class="pun">-</span><span class="pln">R root</span><span class="pun">:</span><span class="pln">root </span><span class="pun">./</span><span class="pln">go
</span><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> mv go </span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="kwd">local</span></code></pre>

<p>
	<strong>ملحوظة:</strong> المسار <code>usr/local/go/</code> هو المسار المنصوح به رسميا لتثبيت Go إلا أن بعض الحالات قد تتطلّب تثبيته على مسار مختلف.
</p>

<h2 id="الخطوة-الثانية-ضبط-مسارات-go">
	الخطوة الثانية: ضبط مسارات Go
</h2>

<p>
	سنضبُط في هذه الخطوة المسارات الخاصّة بـGo في بيئة النظام.
</p>

<p>
	نفتح الملف <code>profile./~</code> لتحريره:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> nano </span><span class="pun">~/.</span><span class="pln">profile</span></code></pre>

<p>
	نضيف السطرين التاليّين في نهاية الملف لضبط قيمة المتغيّر <code>GOPATH</code>، الذي يحدّد المسار الذي يجب على المصرّف البحثُ فيه عن الملفات المكتوبة بـGo، ولإضافة هذا المسار إلى <a href="https://academy.hsoub.com/questions/123-%D9%85%D8%A7%D8%B0%D8%A7-%D9%8A%D8%B9%D9%86%D9%8A-%D9%85%D8%AA%D8%BA%D9%8A%D8%B1-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-path%D8%9F/?do=findComment&amp;comment=251" rel="">متغيّر النظام <code>PATH</code></a>:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs ruby"><span class="kwd">export</span><span class="pln"> </span><span class="hljs-constant"><span class="pln">GOPATH</span></span><span class="pun">=</span><span class="hljs-variable"><span class="pln">$HOME</span></span><span class="pun">/</span><span class="pln">work
</span><span class="kwd">export</span><span class="pln"> </span><span class="hljs-constant"><span class="pln">PATH</span></span><span class="pun">=</span><span class="hljs-variable"><span class="pln">$PATH</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/usr/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">go</span><span class="pun">/</span><span class="pln">bin</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="hljs-variable"><span class="pln">$GOPATH</span></span><span class="pun">/</span><span class="pln">bin</span></code></pre>

<p>
	أضف الأسطر أدناه إلى الملف بدلا من الأسطر السابقة إن اخترت مسارا غير الذي اخترناه لتثبيت Go. يفترض المثال أن Go مثبَّت في المجلّد الشخصي للمستخدم:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs bash"><span class="hljs-keyword"><span class="kwd">export</span></span><span class="pln"> GOROOT</span><span class="pun">=</span><span class="hljs-variable"><span class="pln">$HOME</span></span><span class="pun">/</span><span class="pln">go
</span><span class="hljs-keyword"><span class="kwd">export</span></span><span class="pln"> GOPATH</span><span class="pun">=</span><span class="hljs-variable"><span class="pln">$HOME</span></span><span class="pun">/</span><span class="pln">work
</span><span class="hljs-keyword"><span class="kwd">export</span></span><span class="pln"> PATH</span><span class="pun">=</span><span class="hljs-variable"><span class="pln">$PATH</span></span><span class="pun">:</span><span class="hljs-variable"><span class="pln">$GOROOT</span></span><span class="pun">/</span><span class="pln">bin</span><span class="pun">:</span><span class="hljs-variable"><span class="pln">$GOPATH</span></span><span class="pun">/</span><span class="pln">bin</span></code></pre>

<p>
	نغلق الملف بعد التحرير ونعتمد التغيير بتنفيذ الأمر <code>source</code>:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">source</span></span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">profile</span></code></pre>

<h2 id="الخطوة-الثالثة-اختبار-التثبيت">
	الخطوة الثالثة: اختبار التثبيت
</h2>

<p>
	نتأكّد بعد أن ثبّتنا Go وضبطنا مساراته من عمله.
</p>

<p>
	أنشئ مجلّدا جديدا لحفظ ملفات Go. مسار هذا الملف هو نفس المسار الذي حدّدناه في المتغيّر <code>GOPATH</code>ضمن الخطوة السابقة:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs perl"><span class="hljs-keyword"><span class="pln">mkdir</span></span><span class="pln"> </span><span class="hljs-variable"><span class="pln">$HOME</span></span><span class="pun">/</span><span class="pln">work</span></code></pre>

<p>
	أنشئ مجلّدات مشاريع Go ضمن هذا المجلد كما في المثال التالي. يمكنك إبدال <code>user</code> في المسار أدناه باسم المستخدم الخاصّ بك على GitHub إن كنت تخطّط لاستخدام <a href="https://academy.hsoub.com/programming/workflow/git/" rel="">Git</a> لإيداع شفرتك البرمجية على <a href="https://academy.hsoub.com/programming/workflow/git/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%A7%D9%87%D9%85-%D9%81%D9%8A-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-%D8%B9%D9%84%D9%89-github-r265/" rel="">GitHub</a>. إن لم تكن تخطّط لذلك فيمكن اختيار تسميات أخرى مثل <code>my_project</code>.
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs perl"><span class="hljs-keyword"><span class="pln">mkdir</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln">p work</span><span class="pun">/</span><span class="pln">src</span><span class="pun">/</span><span class="pln">github</span><span class="pun">.</span><span class="pln">com</span><span class="pun">/</span><span class="pln">user</span><span class="pun">/</span><span class="pln">hello</span></code></pre>

<p>
	ننشئ ملفّ Go بسيطا للتجربة، ونسميه <code>hello</code>:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs ruby"><span class="pln">nano </span><span class="pun">~</span><span class="hljs-regexp"><span class="str">/work/</span><span class="pln">src</span></span><span class="hljs-regexp"><span class="pun">/</span><span class="pln">github</span><span class="pun">.</span><span class="pln">com</span><span class="pun">/</span><span class="pln">user</span></span><span class="hljs-regexp"><span class="pun">/</span><span class="pln">hello</span><span class="pun">/</span><span class="pln">hello</span></span><span class="pun">.</span><span class="pln">go</span></code></pre>

<p>
	ألصق شفرة Go التالية ضمن محرّر النصوص. تستخدم هذه الشفرة حزمة <code>main</code> في Go، تستورد مكتبة <code>fmt</code> لدوالّ الإدخال والإخراج وتضبُط دالة جديدة لطباعة الجملة <code>hello, world</code>.
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs go"><span class="hljs-keyword"><span class="kwd">package</span></span><span class="pln"> main

</span><span class="hljs-keyword"><span class="kwd">import</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"fmt"</span></span><span class="pln">

</span><span class="hljs-keyword"><span class="pln">func</span></span><span class="pln"> main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    fmt</span><span class="pun">.</span><span class="typ">Printf</span><span class="pun">(</span><span class="hljs-string"><span class="str">"hello, world\n"</span></span><span class="pun">)</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	يطبع البرنامج السابق عند تنفيذه بنجاح العبارة <code>hello, world</code>، وهو ما يدلّ على نجاح تصريف Compiling شفرة Go.
</p>

<p>
	احفظ الملف ثم أغلقه؛ ثم صرّفه باستدعاء الأمر <code>go install</code>:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs cmake"><span class="pln">go </span><span class="hljs-keyword"><span class="pln">install</span></span><span class="pln"> github</span><span class="pun">.</span><span class="pln">com</span><span class="pun">/</span><span class="pln">user</span><span class="pun">/</span><span class="pln">hello</span></code></pre>

<p>
	يمكننا الآن تشغيل البرنامج بتنفيذ الأمر <code>hello</code>:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs "><span class="pln">hello</span></code></pre>

<p>
	إن تمّ كل شيء على ما يُرام فستُطبَع العبارة <code>hello, world</code>.
</p>

<p>
	يمكنك معرفة أين يوجد الملف التنفيذي للبرنامج (ناتج التصريف) بتمرير اسمه إلى الأمر <code>which</code>:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs "><span class="pln">which hello</span></code></pre>

<p>
	مثال على المُخرجات:
</p>

<pre class="ipsCode" id="ips_uid_7072_10">
<code class="hljs "><span class="str">/home/</span><span class="pln">user</span><span class="pun">/</span><span class="pln">work</span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">hello</span></code></pre>

<h2 id="خاتمة">
	خاتمة
</h2>

<p>
	يصبح لديك بعد تنزيل حزمة Go وتثبيتها وضبط مساراتها نظام جاهز لاستخدامه في التطوير بلغة Go. يمكنك الآن البدء بتعلم كتابة البرامج بهذه اللغة، راجع قسم البرمجة بلغة Go للمزيد.
</p>

<p>
	ترجمة - بتصرّف - للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-install-go-1-6-on-ubuntu-16-04" rel="external nofollow">How to Install Go 1.6 on Ubuntu 16.04</a> لصاحبه Brennen Bearnes.
</p>
]]></description><guid isPermaLink="false">362</guid><pubDate>Sun, 05 Nov 2017 11:23:53 +0000</pubDate></item><item><title>&#x645;&#x62F;&#x62E;&#x644; &#x625;&#x644;&#x649; &#x627;&#x644;&#x623;&#x645;&#x631; ss &#x641;&#x64A; &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%A3%D9%85%D8%B1-ss-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r357/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_10/21.png.87ec5df6f8752b0e3faba0c54f45e066.png" /></p>

<p>
	يحتوي لينكس على عددٍ هائلٍ من الأدوات التي تلبي كافَّة احتياجات المستخدم؛ إن كانت استخداماتك في مجال التطوير أو الحماية أو إدارة الأنظمة …إلخ. فنظام لينكس هو أفضل خيارٍ من بين أنظمة التشغيل.<br>
	إنَّ الأمر «netstat» هو أحد الأوامر المستخدمة بكثرة في لينكس لإظهار معلومات تفصيليَّة عن الشبكة وكيفية اتصال حاسوبك مع الحواسيب أو الشبكات الأخرى؛ فمن مهامه عرض اتصالات وحالة الشبكة وجداول التوجيه وغيرها من البيانات والمعلومات الإحصائيَّة. ظهر الأمر «ss» باعتباره إصدارًا جديدًا للأمر «netstat» ولكن سرعان ما حلَّ مكانه وأصبح بديلًا له في لينكس نظرًا لما يوفِّره من مزايا مثل السرعة وعرض معلومات أوسع وأكثر تفصيلًا بالإضافة إلى سهولته وبساطته، ويمكنك التأكد من ذلك بتصفح صفحة الدليل لكلا الأمرين.<br>
	يستطيع الأمر «ss» عرض معلومات عن الرزم (packet)، والبروتوكولات TCP و UDP و DCCP و RAW، بالإضافة إلى جميع مقابس الشبكة؛ يمكنه أيضًا الحصول على معلومات تفصيليَّة حول كيفيَّة اتصال حاسوبك مع الحواسيب الأخرى، وإظهار بيانات إحصائيَّة حول بروتوكولات الشبكة والمقابس المتَّصلة؛ إنَّ الحصول على هذا الكم من المعلومات يساعدنا بالتأكيد على حلِّ مختلف مشاكل وأعطال الشبكة، وبالتالي تعتبر هذه الأداة من أهمِّ الأدوات في حقيبة الإسعافات الأوليَّة لمديري الأنظمة.
</p>

<h2 id="الاستخدامات-الأساسية">
	الاستخدامات الأساسيَّة
</h2>

<p>
	يُستخدم الأمر «ss» كغيره من الأوامر التي تعمل على لينكس وذلك بكتابته في سطر الأوامر وإتباعه بخياراته، ويمكن أخذ لمحة أوليّة عن الأمر «ss» وخياراته بقراءة صفحة الدليل لهذا الأمر وذلك باستخدام الأمر «man ss»؛ قد تجد للوهلة الأولى، بعد الاطلاع على صفحة الدليل لكلا الأمرين، أنَّ الأمر «netstat» يحوي كثيرًا من الخيارات خلافًا للأمر «ss» وتظنُّ أنَّ الأول أفضل وأكثر كفاءة من الثاني، والحقيقة خلاف ذلك.<br>
	إن نفذت الأمر «ss» دون أي خيارات فستحصل على معلومات عن الاتصالات لمقابس TCP كما موضح بالصورة.
</p>

<p style="text-align: center;">
	<img alt="ss_a.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="25189" data-unique="0izi94g7y" src="https://academy.hsoub.com/uploads/monthly_2017_10/ss_a.jpg.9e41176a81c2cdbca87315f7eb25fdf5.jpg"></p>

<p>
	يمكن حفظ المعلومات التي حصلت عليها للتو في ملف خارجي لاطلاع عليها لاحقًا باستخدام الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6259_7">
ss &gt; ss_output</pre>

<p>
	قد لا يكون الأمر «ss» كافيًا بعض الأحيان، فإذا أردت الحصول على قائمة بالمقابس التي تستمع للاتصالات. استخدم الخيار ‎-l مع الأمر السابق.
</p>

<pre class="ipsCode" id="ips_uid_6259_7">
<code class="hljs bash"><span class="pln">ss </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">l</span></span></code></pre>

<p>
	يمكن أيضًا استخدام خيارات أخرى مثل الخيار ‎-t لعرض اتصالات TCP، والخيار ‎-u لعرض اتصالات UDP، والخيار ‎-x لعرض مقابس يونكس. توضح الصورة التالية ناتج تنفيذ الأمر ss -x.
</p>

<p style="text-align: center;">
	<img alt="ss_b.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="25190" data-unique="812dlq1me" src="https://academy.hsoub.com/uploads/monthly_2017_10/ss_b.jpg.80430084992695cc863465f71f15dc2d.jpg"></p>

<p>
	استخدام الخيارات السابقة سيعطي قائمةً بالاتصالات الحالية وإذا أردنا معرفة الاتصالات المنصتة فنضيف الخيار ‎-a كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_6259_7">
<code class="hljs lasso"><span class="pln">ss </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">t</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">a</span></span></code></pre>

<p>
	وسيُظهر هذا الأمر جميع مقابس TCP التي تنصت للاتصالات كما تبيِّن الصورة؛ لاحظ أنَّ الخيار الأخير هو خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> وهي تنصت للاتصالات.
</p>

<p style="text-align: center;">
	<img alt="ss_c.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="25191" data-unique="2wkagqfbj" src="https://academy.hsoub.com/uploads/monthly_2017_10/ss_c.jpg.05b4ed41edd2a218061110cc9b539404.jpg"></p>

<p style="text-align: center;">
	 
</p>

<p>
	إن جرَّبت الأداة «netstat» للحصول على المعلومات السابقة فستظهر حقول أخرى مثل اسم العملية <abbr title="Process IDentifier | معرّف العملية أو البرنامج">PID</abbr>، واسم الأمر المسؤول عن هذه الاتصالات وهذا ما يصعِّب من قراءتها.<br>
	بإمكانك الآن معرفة عناوين IP والمنافذ المستخدمة في إنشاء الاتصال بين حاسوبك والحواسيب والشبكات الأخرى والتي ستساعدك لتتمكن من تحليل المشاكل والأعطال وإصلاحها، ولكن مازال هنالك بعضًا من المعلومات تنقصك يجب عليك معرفتها.
</p>

<h2 id="تصفية-النتائج-باستخدام-حالات-اتصال-tcp">
	تصفية النتائج باستخدام حالات اتصال TCP
</h2>

<p>
	تصفية نتائج الأمر «ss» واحد من أكثر الخيارات فائدة؛ تعتمد عملية التصفية على حالات TCP التي تصف مراحل حياة الاتصال، إذ يمر أي جهازان قبل إنشاء اتصال بينهما وحتى إنهائه بمراحل عدَّة، وذلك لحصر المعلومات التي نريد الحصول عليها في مجال ضيق ومحدود. من حالات الاتصال TCP التي يمكن استخدام عملية التصفية معها هي:
</p>

<center>
	<table border="1"><tbody>
<tr>
<td style="background-color: rgb(111, 240, 111); padding: 5px 10px; text-align: center;">
					الحالة
				</td>
				<td style="background-color: rgb(111, 240, 111); padding: 5px 10px; text-align: center;">
					شرح الحالة
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					closed<br>
					“غير مُنشأ”
				</td>
				<td style=" padding: 5px 10px;">
					هي الحالة الافتراضيَّة التي يكون فيها الجهاز قبل بدء عملية تأسيس الاتصال، أي أنَّ الجهاز غير متصل مع أحد.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					listening<br>
					“استماع”
				</td>
				<td style=" padding: 5px 10px;">
					يكون الجهاز (غالبًا الخادم) في هذه الحالة بانتظار استلام رسالة تزامن (SYN اختصارًا للعبارة synchronize) من العميل.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					syn-sent<br>
					“’طلب التزامن”
				</td>
				<td style=" padding: 5px 10px;">
					يرسل في هذه الحالة أحد الجهازين (غالبًا العميل) رسالة تزامن (SYN) إلى الجهاز الذي يريد بدء وتأسيس اتصال معه، وينتظر منه بالمقابل الرد برسالة تزامن أخرى.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					sys-recv<br>
					“تأكيد التزامن”
				</td>
				<td style=" padding: 5px 10px;">
					أرسل كلا الجهازين في هذه الحالة رسالة تزامن وينتظران تقرير الاستلام لهذه الرسائل لإنهاء إعداد وتهيئة الاتصال بينهما.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					established<br>
					“مُنشأ”
				</td>
				<td style=" padding: 5px 10px;">
					وهي الحالة الثابتة والمستقرة للاتصال بين جهازين، ويمكن بدء تبادل البيانات بينهما متى دخل كلا الجهازين في هذه الحالة وذلك بعد أن يكون كلٌّ منها قد أرسل رسالة تزامنٍ واستلم تقرير التوصيل من الآخر.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					close-wait<br>
					“بدء إنهاء الاتصال”
				</td>
				<td style=" padding: 5px 10px;">
					استلم في هذه الحالة أحد الجهازين رسالةً لإنهاء الاتصال (FIN)، اختصارًا للعبارة (finish)، من الآخر وهو بانتظار تأكيد هذه الرسالة لإنهاء الاتصال معه.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					fin-wait-1<br>
					“انتظار إنهاء الاتصال-1”
				</td>
				<td style=" padding: 5px 10px;">
					يكون الجهاز -الذي يريد قطع الاتصال- في هذه الحالة بانتظار تقرير استلام رسالة إنهاء الاتصال (FIN) أو قطع الاتصال التي أرسلها للجهاز المقابل.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					fin-wait-2<br>
					“انتظار إنهاء الاتصال-2”
				</td>
				<td style=" padding: 5px 10px;">
					يدخل الجهاز في هذه الحالة بعد استلام تقريرٍ عن توصيل رسالة إنهاء الاتصال التي أرسلها للجهاز الآخر وهو بانتظار رسالة (FIN) لتأكيد إنهاء الاتصال منه.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					closing<br>
					“تأكيد إنهاء الاتصال”
				</td>
				<td style=" padding: 5px 10px;">
					يدخل بها الجهاز بعد استلام رسالة إنهاء الاتصال (FIN) وإرسال تقرير باستلامها إلى الجهاز الآخر الذي يريد قطع الاتصال.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					last-ack<br>
					“تقرير الاستلام الأخير”
				</td>
				<td style=" padding: 5px 10px;">
					أرسل أحد الجهازين تقريرًا باستلام رسالة (FIN) من الجهاز الآخر الذي يريد قطع الاتصال ثم أعاد إرسال الرسالة (FIN) له لتأكيد قطع الاتصال وهو الآن بانتظار آخر تقرير يؤكد استلام هذه الرسالة.
				</td>
			</tr>
<tr>
<td style=" padding: 5px 10px; text-align: center;">
					time-wait<br>
					“مهلة إنهاء الاتصال”
				</td>
				<td style=" padding: 5px 10px;">
					هو الوقت الذي ينتظره الجهاز بعد إرسال تقريره الأخير (last-ack) للتأكد من أنَّ الجهاز المقابل قد استلمه، وبعد انتهاء المهلة تصبح حالة هذا الجهاز “غير متصل” (closed).
				</td>
			</tr>
</tbody></table>
</center>

<p>
	هنالك أيضًا حالات متاحة يمكن استعمالها مع الأمر «ss» وهي:
</p>

<ul>
<li>
		all: اختيار جميع الحالات السابقة.
	</li>
	<li>
		connected: جميع الحالات السابقة باستثناء حالتي الاتصال “غير مُنشأ” (closed) و “استماع” (listening).
	</li>
	<li>
		synchronized: جميع حالات الخيار السابق باستثناء حالة إرسال رسالة التزامن (sys-sent).
	</li>
	<li>
		bucket: تشمل الحالتان sys-recv و time-wait.
	</li>
	<li>
		big: عكس الخيار السابق.
	</li>
</ul>
<p>
	إن وجدت نفسك تائهًا في دوامة تلك الحالات، أعد قراءتها بهدوء.<br>
	طريقة كتابة الأمر «ss» وتصفية النتائج سهلة، وهي للعنوان Ipv4:
</p>

<pre class="ipsCode" id="ips_uid_6259_7">
<code class="hljs perl">ss -<span class="hljs-number">4</span> <span class="hljs-keyword">state</span> FILTER  </code></pre>

<p>
	أما للعنوان IPv6 فهو:
</p>

<pre class="ipsCode" id="ips_uid_6259_7">
<code class="hljs perl">ss -<span class="hljs-number">6</span> <span class="hljs-keyword">state</span> FILTER</code></pre>

<p>
	غير العبارة “FILTER” إلى واحدة من الحالات السابقة. ومثال على ذلك استخدام الأمر التالي لعرض المقابس في حالة الاستماع:
</p>

<pre class="ipsCode" id="ips_uid_6259_7">
<code class="hljs perl">ss -<span class="hljs-number">4</span> <span class="hljs-keyword">state</span> listening</code></pre>

<p>
	والنتائج التي ستحصل عليها هي كما مبيَّنة في الصورة.
</p>

<p style="text-align: center;">
	<img alt="ss_d.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="25192" data-unique="qe8pmcisl" src="https://academy.hsoub.com/uploads/monthly_2017_10/ss_d.jpg.95ec9b168638e7bc9dd94102ecaf0210.jpg"></p>

<h2 id="عرض-المقابس-المتصلة-بعناوين-محددة">
	عرض المقابس المتصلة بعناوين محدَّدة
</h2>

<p>
	توفِّر الأداة «ss» وسيلة للحصول على معلومات عن الاتصالات التي تنشأ مع عناوين IP محدَّدة؛ إن أردت معرفة فيما إذا كان الجهاز ذو العنوان 192.168.1.139 على سبيل المثال متصلًا بخادمك، فنفذ الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_6259_7">
<code class="hljs nginx"><span class="hljs-title">ss</span> dst <span class="hljs-number">192.168.1.139</span></code></pre>

<p>
	ستحصل على معلوماتٍ شبيهةٍ بتلك الموجودة في الصورة التالية:
</p>

<p style="text-align: center;">
	<img alt="ss_e.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="25193" data-unique="t8t0y4nsa" src="https://academy.hsoub.com/uploads/monthly_2017_10/ss_e.jpg.ad5ddb4d27709be442a4075d7db6d25d.jpg"></p>

<h2 id="حان-دورك-الآن">
	حان دورك الآن
</h2>

<p>
	عرضنا في هذا المقال بعضًا من الخيارات الأساسيَّة للأمر «ss» التي يفترض الإلمام بها والتي ستساعدك في تحليل وإصلاح المشاكل التي قد يتعرض لها خادمك أو شبكتك أثناء عملهم؛ توجَّه مباشرة بعد الانتهاء من هذه المقالة نحو صفحة الدليل للأمر «ss» للتعرُّف على المزيد من المهام والخيارات.<br>
	ترجمة -وبتصرف- للمقال<a href="https://www.linux.com/learn/intro-to-linux/2017/7/introduction-ss-command" rel="external nofollow"> an introduction to the ss command</a> لصاحبه Jack Wallen.
</p>
]]></description><guid isPermaLink="false">357</guid><pubDate>Fri, 20 Oct 2017 05:51:21 +0000</pubDate></item><item><title>&#x639;&#x634;&#x631;&#x648;&#x646; &#x623;&#x645;&#x631;&#x627; &#x641;&#x64A; &#x644;&#x64A;&#x646;&#x643;&#x633; &#x64A;&#x641;&#x62A;&#x631;&#x636; &#x623;&#x646; &#x64A;&#x639;&#x631;&#x641;&#x647;&#x627; &#x643;&#x644; &#x645;&#x62F;&#x64A;&#x631; &#x646;&#x638;&#x645;</title><link>https://academy.hsoub.com/devops/linux/%D8%B9%D8%B4%D8%B1%D9%88%D9%86-%D8%A3%D9%85%D8%B1%D8%A7-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D9%8A%D9%81%D8%AA%D8%B1%D8%B6-%D8%A3%D9%86-%D9%8A%D8%B9%D8%B1%D9%81%D9%87%D8%A7-%D9%83%D9%84-%D9%85%D8%AF%D9%8A%D8%B1-%D9%86%D8%B8%D9%85-r355/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_06/5eeaf33757f09_---------.jpg.cd48b0d25696b700e5ec39f273d322bf.jpg" /></p>

<p>
	من الضروري على أي مطور أو مهندس تعلُّم بعض أوامر إدارة النظام الأساسيَّة خصوصًا في ظل غزو أدوات جديدة وبيئات متطورة ومتنوعة عالمنا بشكل دائم؛ يمكن لأوامر وحزم معيَّنة أن تساعد المطورين على تنظيم وإدارة واستكشاف أخطاء التطبيقات ومحاولة إصلاحها، كما تزودهم بمعلومات مفيدة عن حالة النظام والتطبيقات.<br>
	سواءً كنت مطورًا جديدًا أو تريد إدارة تطبيقاتك فحسب فإنَّ الأوامر العشرون التي يشرحها هذا الدليل ، ستساعدك على فهمٍ أفضلٍ لتطبيقاتك، أو تعطيك القدرة على وصف المشاكل التي تعترضك في العمل لمديري الأنظمة لإصلاحها، مثلًا لماذا يعمل التطبيق محليًا ولكنه ليس على المضيف البعيد؟ تطبَّق هذه الأوامر ضمن بيئة لينكس والنظام الحاسوبي الذي يحوي أنظمة وهمية مثبتة عليه مباشرة (bare metal environment) والحاويات.
</p>

<h2 id="1-curl">
	1. curl
</h2>

<p>
	إنَّ curl هو أداةٌ لنقل الملفات باستخدام رابط URL عبر سطر الأوامر؛ يُستخدم هذا الأمر أيضًا لفحص اتصال التطبيقات مع خدمة ما، أي بمعنى آخر تحديد فيما إذا كان تطبيقك يستطيع الوصول إلى خدمة معينة مثل قاعدة بيانات، أو التحقق إن كانت الخدمة بحد ذاتها تعمل بشكل صحيح.<br>
	لنفترض مثلًا أن تطبيقك يُظهر الخطأ HTTP 500 الذي يشير إلى عدم قدرته الوصول إلى قاعدة البيانات MongoDB.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
$ curl -I -s myapplication:5000
HTTP/1.0 500 INTERNAL SERVER ERROR</pre>

<p>
	الخيار ‎-I (أو ‎–head) يُظهر معلومات ترويسة http فقط، والخيار ‎-s (أو ‎–silent) يُخفي تفاصيل تقدم العملية أو رسائل الخطأ. يمكنك في هذه الحالة تفقُّد نقطة النهاية لقاعدة بياناتك من حاسوبك المحلي كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_2543_8">
$ curl -I -s database:27017
HTTP/1.0 200 OK</pre>

<p>
	لا توجد مشكلة، إذا أين تكمن المشكلة؟! تأكد إن كان تطبيقك يستطيع الوصول إلى أماكن أخرى بالإضافة إلى قاعدة البيانات من تطبيق المضيف.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs lasso"><span class="pln">$ curl </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">I</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">s</span></span><span class="pln"> https</span><span class="pun">:</span><span class="hljs-comment"><span class="com">//opensource.com</span></span><span class="pln">
HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">200</span></span><span class="pln"> OK</span></code></pre>

<p>
	لا مشكلة أيضًا؛ حاول الآن الوصول إلى قاعدة البيانات من تطبيق المضيف؛ يَستخدم تطبيقك اسم مضيف قاعدة البيانات لذا جرِّبه أولًا.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs ruby"><span class="hljs-variable"><span class="pln">$ </span></span><span class="pln">curl </span><span class="hljs-symbol"><span class="pln">database</span><span class="pun">:</span></span><span class="hljs-number"><span class="lit">27017</span></span><span class="pln">
</span><span class="hljs-symbol"><span class="pln">curl</span><span class="pun">:</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-number"><span class="lit">6</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-constant"><span class="typ">Couldn</span></span><span class="hljs-string"><span class="str">'t resolve host '</span></span><span class="pln">database</span><span class="hljs-string"><span class="str">'</span></span></code></pre>

<p>
	يشير ذلك إلى أنَّ تطبيقك لا يستطيع أن يستبين عنوان خادوم قاعدة البيانات إذ إمَّا أن يكون غير متوافر أو أنَّ المضيف (الحاوية أو الجهاز الافتراضي) لا<br>
	يملك اسم خادوم ليستبين عن اسم المضيف.
</p>

<h2 id="2-python-m-jsontool-jq">
	2. python -m json.tool / jq
</h2>

<p>
	بعد تنفيذ الأمر curl ستجد أن ناتجه صعب القراءة. تحتاج أحيانًا إلى طباعة المخرجات بصيغة جميلة ومنسَّقة وقابلة للقراءة للبحث عن مدخلات معيَّنة وهذا ما توفره صيغة البيانات JSON، التي هي صيغة سلسة وسهلة القراءة والفهم وتُستخدم لنقل البيانات بين لغات البرمجة أو بين تطبيقات الويب والخادوم؛ توجد مكتبة JSON مدمجة في بايثون يمكن أن تساعدنا في هذه العملية عبر استعمال الأمر python -m json.tool بعد تحويل المخرجات إليه.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs ruby"><span class="hljs-variable"><span class="pln">$ </span></span><span class="pln">cat test</span><span class="pun">.</span><span class="pln">json
</span><span class="pun">{</span><span class="hljs-string"><span class="str">"title"</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="hljs-string"><span class="str">"Person"</span></span></span><span class="pun">,</span><span class="hljs-string"><span class="str">"type"</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="hljs-string"><span class="str">"object"</span></span></span><span class="pun">,</span><span class="hljs-string"><span class="str">"properties"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">{</span><span class="hljs-string"><span class="str">"firstName"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">{</span><span class="hljs-string"><span class="str">"type"</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="hljs-string"><span class="str">"string"</span></span></span><span class="pun">},</span><span class="hljs-string"><span class="str">"lastName"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">{</span><span class="hljs-string"><span class="str">"type"</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="hljs-string"><span class="str">"string"</span></span></span><span class="pun">},</span><span class="hljs-string"><span class="str">"age"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">{</span><span class="hljs-string"><span class="str">"description"</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="hljs-string"><span class="str">"Age in years"</span></span></span><span class="pun">,</span><span class="hljs-string"><span class="str">"type"</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="hljs-string"><span class="str">"integer"</span></span></span><span class="pun">,</span><span class="hljs-string"><span class="str">"minimum"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="hljs-number"><span class="lit">0</span></span><span class="pun">}},</span><span class="hljs-string"><span class="str">"required"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">[</span><span class="hljs-string"><span class="str">"firstName"</span></span><span class="pun">,</span><span class="hljs-string"><span class="str">"lastName"</span></span><span class="pun">]}</span></code></pre>

<p>
	هل فهمت شيئًا من المخرجات السابقة؟ سنستخدم صيغة JSON في الأمر التالي بإرسال المخرجات السابقة إلى بايثون.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs avrasm"><span class="pln">$ cat test</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">json</span></span><span class="pln"> </span><span class="pun">|</span><span class="pln"> python </span><span class="pun">-</span><span class="pln">m json</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">tool</span></span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"properties"</span></span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-string"><span class="str">"age"</span></span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-string"><span class="str">"description"</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="str">"Age in years"</span></span><span class="pun">,</span><span class="pln">
            </span><span class="hljs-string"><span class="str">"minimum"</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-number"><span class="lit">0</span></span><span class="pun">,</span><span class="pln">
            </span><span class="hljs-string"><span class="str">"type"</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="str">"integer"</span></span><span class="pln">
        </span><span class="pun">},</span><span class="pln">
        </span><span class="hljs-string"><span class="str">"firstName"</span></span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-string"><span class="str">"type"</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="str">"string"</span></span><span class="pln">
        </span><span class="pun">},</span><span class="pln">
        </span><span class="hljs-string"><span class="str">"lastName"</span></span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-string"><span class="str">"type"</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="str">"string"</span></span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">},</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"required"</span></span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
        </span><span class="hljs-string"><span class="str">"firstName"</span></span><span class="pun">,</span><span class="pln">
        </span><span class="hljs-string"><span class="str">"lastName"</span></span><span class="pln">
    </span><span class="pun">],</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"title"</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="str">"Person"</span></span><span class="pun">,</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"type"</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="str">"object"</span></span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	هل لاحظت الفرق؟! يمكن إظهار المخرجات أيضًا بطريقة متقدمة تشبه استخدام الأمر السابق وهو بتحويل المخرجات إلى الأداة <a href="https://stedolan.github.io/jq/manual/v1.5/" rel="external nofollow">jq</a> والتي تحوي خيارات عدَّة للحصول على قيم محدَّدة من مدخلات صيغة JSON؛ يمكنك تثبيت jd <a href="https://stedolan.github.io/jq/download/" rel="external nofollow">من هذا الرابط</a>.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs ruby"><span class="hljs-variable"><span class="pln">$ </span></span><span class="pln">cat test</span><span class="pun">.</span><span class="pln">json </span><span class="pun">|</span><span class="pln"> jq
</span><span class="pun">{</span><span class="pln">
  </span><span class="hljs-string"><span class="str">"title"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"Person"</span></span><span class="pun">,</span><span class="pln">
  </span><span class="hljs-string"><span class="str">"type"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"object"</span></span><span class="pun">,</span><span class="pln">
  </span><span class="hljs-string"><span class="str">"properties"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"firstName"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="hljs-string"><span class="str">"type"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"string"</span></span><span class="pln">
    </span><span class="pun">},</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"lastName"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="hljs-string"><span class="str">"type"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"string"</span></span><span class="pln">
    </span><span class="pun">},</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"age"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="hljs-string"><span class="str">"description"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"Age in years"</span></span><span class="pun">,</span><span class="pln">
      </span><span class="hljs-string"><span class="str">"type"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"integer"</span></span><span class="pun">,</span><span class="pln">
      </span><span class="hljs-string"><span class="str">"minimum"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">},</span><span class="pln">
  </span><span class="hljs-string"><span class="str">"required"</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pln"> </span><span class="pun">[</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"firstName"</span></span><span class="pun">,</span><span class="pln">
    </span><span class="hljs-string"><span class="str">"lastName"</span></span><span class="pln">
  </span><span class="pun">]</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<h2 id="3-ls">
	3. ls
</h2>

<p>
	يُستعمل الأمر ls لإظهار قائمة بالملفات الموجودة ضمن مجلد، ويستخدمه مديرو الأنظمة والمطورون بكثرة؛ يمكن أيضًا باستخدام هذا الأمر لإيجاد ملف معين ما بالإضافة إلى عرض أذوناته.<br>
	حاولنا في المثال التالي تشغيل الملف myapp ولكنَّنا لم نستطع بسبب مشكلة الأذونات؛ عندما تفحصنا الأذونات عبر الأمر ls -l وجدنا أن الملف صالح للقراءة والكتابة فقط.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs lasso"><span class="pln">$ </span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pun">/</span><span class="pln">myapp
bash</span><span class="pun">:</span><span class="pln"> </span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pun">/</span><span class="pln">myapp</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Permission</span><span class="pln"> denied
$ ls </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">l</span></span><span class="pln"> myapp
</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">rw</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">r</span></span><span class="hljs-subst"><span class="pun">--</span></span><span class="pln">r</span><span class="hljs-subst"><span class="pun">--</span></span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> root root </span><span class="hljs-number"><span class="lit">33</span></span><span class="pln"> </span><span class="typ">Jul</span><span class="pln"> </span><span class="hljs-number"><span class="lit">21</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">18</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">36</span></span><span class="pln"> myapp</span></code></pre>

<h2 id="4-tail">
	4. tail
</h2>

<p>
	يُظهر الأمر tail الجزء الأخير من الملف؛ لا تحتاج غالبًا إلى قراءة جميع أسطر الملف أو السجل أثناء البحث ضمنهم عن مشكلة أو عطل ما ولكن قد تكون البيانات الأخيرة (الأحدث) هي الأهم. تستطيع مثلًا استعمال الأمر tail لفحص ومعرفة ما ذا يحدث في السجلات عندما تنشئ طلبية HTTP.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs coffeescript"><span class="pun">[</span><span class="pln">root</span><span class="hljs-property"><span class="pln">@localhost</span></span><span class="pln"> </span><span class="pun">~]</span><span class="hljs-comment"><span class="pun">#</span><span class="pln"> tail </span><span class="pun">-</span><span class="pln">f </span><span class="pun">/</span><span class="kwd">var</span><span class="pun">/</span><span class="pln">log</span><span class="pun">/</span><span class="pln">httpd</span><span class="pun">/</span><span class="pln">access_log</span></span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">46</span><span class="pun">:</span><span class="lit">58</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">00</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">02</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">04</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">06</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">08</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">10</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">12</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">14</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span><span class="pln">
</span><span class="pun">::</span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="pun">[</span><span class="hljs-number"><span class="lit">21</span></span><span class="pun">/</span><span class="typ">Jul</span><span class="hljs-regexp"><span class="pun">/</span><span class="lit">2017</span><span class="pun">:</span><span class="lit">18</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">16</span><span class="pln"> </span><span class="pun">+</span><span class="lit">0000</span><span class="pun">]</span><span class="pln"> </span><span class="pun">“</span><span class="pln">GET </span><span class="pun">/</span></span><span class="pln"> HTTP</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1.1</span></span><span class="pun">”</span><span class="pln"> </span><span class="hljs-number"><span class="lit">403</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4897</span></span><span class="pln"> </span><span class="pun">“-”</span><span class="pln"> </span><span class="pun">“</span><span class="pln">curl</span><span class="pun">/</span><span class="hljs-number"><span class="lit">7.29</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pun">”</span></code></pre>

<p>
	الخيار ‎-f (أو ‎–follow) يُظهر أسطر السجل أو الملف التي تُضاف إليه حديثًا، وهذا واضح من المثال السابق. يمكن إظهار عدد محدَّد من الأسطر عوضًا عن تتبع تحديثات الملف وإظهارها مثل إظهار آخر 100 سطر من الملف عبر الخيار ‎-n.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs lasso"><span class="pln">$ tail </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">100</span></span><span class="pln"> </span><span class="pun">/</span><span class="hljs-built_in"><span class="kwd">var</span></span><span class="pun">/</span><span class="hljs-keyword"><span class="pln">log</span></span><span class="pun">/</span><span class="pln">httpd</span><span class="pun">/</span><span class="pln">access_log</span></code></pre>

<h2 id="5-cat">
	5. cat
</h2>

<p>
	يعمل هذا الأمر على دمج الملفات أو طباعتها إلى مجرى الخرج القياسي كما يُستخدم للتحقق من محتويات الملفات.<br>
	نتأكد في المثال التالي إن كان إطار العمل Flask، وهو إطار عمل مصغَّر لتطوير تطبيقات ويب صغيرة ومتوسطة، مُدرجًا ضمن القائمة التي يعتمد عليها التطبيق Python Flask.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs ruby"><span class="hljs-variable"><span class="pln">$ </span></span><span class="pln">cat requirements</span><span class="pun">.</span><span class="pln">txt
flask
flask_pymongo</span></code></pre>

<h2 id="6-grep">
	6. grep
</h2>

<p>
	الأداة grep هي أداةٌ قويةٌ في مطابقة أنماط نصيَّة داخل الملفات؛ إن كنت تبحث عن نمط نصي معين داخل ملف أو في مخرجات أمرٍ آخر فيمكن استخدام هذه الأداة للبحث عن هذا النمط وتحديد مكان وجوده.<br>
	لنفترض مثلًا أنَّك تريد التأكد من عمل الخادوم Apache Tomcat، ستعجز عن قراءة الكثير من الأسطر للبحث عنه لذا يمكن إرسال المخرجات إلى الأمر grep لعزل الأسطر التي تشير إليه.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs avrasm"><span class="pln">$ cat tomcat</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">log</span></span><span class="pln"> </span><span class="pun">|</span><span class="pln"> grep org</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">apache</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">catalina</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">startup</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">Catalina</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">start</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">01</span></span><span class="pun">-</span><span class="typ">Jul</span><span class="pun">-</span><span class="hljs-number"><span class="lit">2017</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">18</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">03</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">47.542</span></span><span class="pln"> INFO </span><span class="pun">[</span><span class="pln">main</span><span class="pun">]</span><span class="pln"> org</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">apache</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">catalina</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">startup</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">Catalina</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">start</span></span><span class="pln"> </span><span class="typ">Server</span><span class="pln"> startup </span><span class="hljs-keyword"><span class="kwd">in</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">681</span></span><span class="pln"> ms</span></code></pre>

<h2 id="7-ps">
	7. ps
</h2>

<p>
	يُظهر الأمر ps حالة العمليات التي تعمل حاليًا في النظام؛ يُستعمل لتحديد التطبيقات التي تعمل أو للتأكد من عملية ما، فإذا أردت التحقق من عمل خادوم الويب Tomcat، استعمل الأمر ps مع الخيارات التالية للحصول على رقم العملية لهذا الخادوم.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs lasso"><span class="pln">$ ps </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">ef</span></span><span class="pln">
UID        <abbr title="Process IDentifier | معرّف العملية أو البرنامج">PID</abbr>  PPID  C STIME TTY          TIME CMD
root         </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln">     </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">  </span><span class="hljs-number"><span class="lit">2</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">18</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">55</span></span><span class="pln"> </span><span class="hljs-subst"><span class="pun">?</span></span><span class="pln">        </span><span class="hljs-number"><span class="lit">00</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">00</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">02</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">docker</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">java</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">home</span></span><span class="pun">/</span><span class="pln">jre</span><span class="pun">/</span><span class="pln">bi
root        </span><span class="hljs-number"><span class="lit">59</span></span><span class="pln">     </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">  </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">18</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">55</span></span><span class="pln"> pts</span><span class="pun">/</span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">00</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">00</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">00</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">sh
root        </span><span class="hljs-number"><span class="lit">75</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">59</span></span><span class="pln">  </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">18</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">57</span></span><span class="pln"> pts</span><span class="pun">/</span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">00</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">00</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">00</span></span><span class="pln"> ps </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">ef</span></span></code></pre>

<p>
	ولتجنب قراءة الكثير من الأسطر والعمليات، أرسل المخرجات السابقة إلى الأداة grep كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs lasso"><span class="pln">$ ps </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">ef</span></span><span class="pln"> </span><span class="hljs-subst"><span class="pun">|</span></span><span class="pln"> grep tomcat
root         </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln">     </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">  </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">18</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">55</span></span><span class="pln"> </span><span class="hljs-subst"><span class="pun">?</span></span><span class="pln">        </span><span class="hljs-number"><span class="lit">00</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">00</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">02</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">docker</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">java</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">home</span></span><span class="pun">/</span><span class="pln">jre</span><span class="pun">/</span><span class="pln">bi</span></code></pre>

<h2 id="8-env">
	8. env
</h2>

<p>
	يتيح الأمر env عرض <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%B7%D8%B1%D9%81%D9%8A%D9%91%D8%A9-%D9%84%D9%8A%D9%86%D9%83%D8%B3-linux-terminal-r18/" rel="">متغيرات البيئة</a> التي ضُبطت لجلسة طرفيَّة معيَّنة؛ قد يكون من المفيد في أثناء البحث عن المشاكل والأعطال التأكد من عدم وجود متغير خاطئ يمنع تطبيقك من البدء.<br>
	سنستخدم الأمر env في المثال التالي للتحقق من متغيرات البيئة المضبوطة للتطبيقات.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs makefile"><span class="pln">$ env
</span><span class="hljs-constant"><span class="pln">PYTHON_PIP_VERSION</span></span><span class="pun">=</span><span class="lit">9.0</span><span class="pun">.</span><span class="lit">1</span><span class="pln">
</span><span class="hljs-constant"><span class="pln">HOME</span></span><span class="pun">=/</span><span class="pln">root
</span><span class="hljs-constant"><span class="pln">DB_NAME</span></span><span class="pun">=</span><span class="pln">test
</span><span class="hljs-constant"><span class="pln">PATH</span></span><span class="pun">=</span><span class="str">/usr/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">bin</span><span class="pun">:</span><span class="str">/usr/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">sbin
</span><span class="hljs-constant"><span class="pln">LANG</span></span><span class="pun">=</span><span class="pln">C</span><span class="pun">.</span><span class="pln">UTF</span><span class="pun">-</span><span class="lit">8</span><span class="pln">
</span><span class="hljs-constant"><span class="pln">PYTHON_VERSION</span></span><span class="pun">=</span><span class="lit">3.4</span><span class="pun">.</span><span class="lit">6</span><span class="pln">
</span><span class="hljs-constant"><span class="pln">PWD</span></span><span class="pun">=/</span><span class="pln">
</span><span class="hljs-constant"><span class="pln">DB_URI</span></span><span class="pun">=</span><span class="pln">mongodb</span><span class="pun">:</span><span class="com">//database:27017/test</span></code></pre>

<p>
	لاحظ أن التطبيق يستخدم “بايثون 3” ويحوي متغيرًا للبيئة للاتصال بقاعدة البيانات MongoDB.
</p>

<h2 id="9-top">
	9. top
</h2>

<p>
	يطبع الأمر top قائمة بالعمليات التي تجري في النظام بطريقة أكثر تفاعلية من الأمر ps كما يرتِّب العمليات حسب نشاطها ويحدِّث القائمة كلَّ ثلاث ثوانٍ؛ يمكن باستخدام هذه الأداة تحديد كمية الذاكرة والمعالج التي تستهلكها كلُّ عملية على حدة. قد تحدث حالة شائعة عند تشغيل تطبيق وهي توقفه عن العمل ثمَّ جموده، فيجب أولًا في هذه الحالة التحقق من الخطأ الذي يظهره التطبيق والذي قد يكون خطأ في الذاكرة.
</p>

<pre class="ipsCode" id="ips_uid_2543_10">
<code class="hljs sql"><span class="pln">$ tail myapp</span><span class="pun">.</span><span class="pln">log
</span><span class="typ">Traceback</span><span class="pln"> </span><span class="pun">(</span><span class="pln">most recent </span><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">call</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">last</span></span><span class="pun">):</span><span class="pln">
</span><span class="typ">MemoryError</span></span></code></pre>

<p>
	هل حقًا الذاكرة لا تكفي أو يوجد خطأ فيها؟ للتثبُّت من ذلك نستخدم الأمر top لمعرفة كمية الذاكرة والمعالج التي يستهلكها التطبيق؛ عند تنفيذ الأمر نلاحظ أنَّ التطبيق “بايثون” يستخدم نسبة كبيرة من المعالج والذاكرة، وما توقعناه كان صحيحًا.
</p>

<p style="text-align: center;">
	<img alt="01_example_top.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25154" data-unique="sode861n7" src="https://academy.hsoub.com/uploads/monthly_2017_10/01_example_top.png.49577ae9ff3949faa199f67c1ed61d4d.png"></p>

<p>
	أثناء تشغيل الأداة top اضغط على C لرؤية موقع الأمر كاملًا وربط كل عملية مع تطبيق محدد.
</p>

<p style="text-align: center;">
	<img alt="02_example_top.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25152" data-unique="duq3z343c" src="https://academy.hsoub.com/uploads/monthly_2017_10/02_example_top.png.7e53fbb5a47a57af438f7f330c02be37.png"></p>

<p>
	تبيَّن أنَّ التطبيق “memeater.py” يستهلك أغلب الذاكرة. عندما تنفد الذاكرة نتيجة استهلاكها من أحد التطبيقات فإنَّ النظام ينهي (يقتل kill) هذا التطبيق أو العملية ويرسل خطأ نفاد الذاكرة (out-of-memory) اختصارًا (OOM).
</p>

<h2 id="10-netstat">
	10. netstat
</h2>

<p>
	إنَّ وظيفة الأمر netstat هي عرض حالة الشبكة والمنافذ المستخدمة والاتصالات الواردة عبرها. هذه الأداء لا تكون مدمجة في لينكس لذا تحتاج إلى تثبيتها عبر الحزمة <a href="https://wiki.linuxfoundation.org/networking/net-tools?s%5B%5D=netstat" rel="external nofollow">net-tools</a>. من المحتمل أن تصادف خطأ -إن كنت مطورًا- يشير إلى أن المنفذ محجوز أو العنوان مستخدم حاليًا …إلخ. فيمكن استعمال الأمر netstat لتحليل وفحص الأعطال لمحاولة إصلاحها. يوضح المثال التالي أنَّ أباتشي يستخدم المنفذ 80 على الجهاز عند تنفيذ الأمر التالي:
</p>

<p style="text-align: center;">
	<img alt="03_example_netstat.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25153" data-unique="53twr4022" src="https://academy.hsoub.com/uploads/monthly_2017_10/03_example_netstat.png.90b4a12767902cf2b033f66c59affd49.png"></p>

<p>
	حيث يشير الخيار t إلىTCP والخيار u إلى UDP و l إلى listening (حالة الاستماع) و n إلى numeric.
</p>

<h2>
	11. ip address
</h2>

<p>
	يعمل الأمر ip address على عرض الواجهات وعناوين IP لتطبيقات المضيف أو التحقق من عنوان IP للحاوية؛ إن لم يكن الأمر موجودًا أو لم يعمل فيمكنك تثبيته عبر الحزمة <a href="https://wiki.linuxfoundation.org/networking/iproute2" rel="external nofollow">iproute2</a>.
</p>

<p>
	إن كانت حاويتك متصلة مثلًا مع شبكتين فإنَّ الأمر ip address يبين الواجهة المتصلة مع كل شبكة؛ يمكن أيضًا استخدام هذا الأمر للحصول على عنوان IP للجهاز المضيف. يوضح المثال التالي أنَّ عنوان IP لحاوية الويب على الواجهة eth0 هو 172.17.0.2:
</p>

<p style="text-align: center;">
	<img alt="01_example_ipaddr_0.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25359" data-unique="pgh5159pk" src="https://academy.hsoub.com/uploads/monthly_2017_11/01_example_ipaddr_0.png.6105557fe49011bfbab383c289703ead.png"></p>

<h2>
	12. lsof
</h2>

<p>
	يُستخدم الخيار lsof لسرد قائمة بالملفات المفتوحة (list open files) وربطها مع التطبيقات؛ قد لا يتواجد هذا الأمر في بعض توزيعات لينكس لذا ثبِّت الحزمة lsof.
</p>

<p>
	هنالك مقولة مشهورة وهي: "يُعامَل أي تفاعل مع النظام في لينكس على أنَّه ملف"، وبذلك إن كان هنالك تطبيق يكتب على ملف أو ينشئ اتصالًا على الشبكة فإنَّ الأمر lsof سيعتبره ملفًا.
</p>

<p>
	يُستخدم أيضًا هذا الأمر بصورة مشابهة للأمر netstat وذلك في عرض المنافذ المنصتة. إن أردت مثلًا التحقق من كون المنفذ 80 مستخدم حاليًا أو لا، فاستعمل الأمر lsof مع الخيار ‎-i الذي يعطي قائمة بالملفات المفتوحة المرتبطة باتصال عبر الشبكة الموافقة لما بعد الخيار. توضح الصورة التالية خادوم أباتشي (httpd) يستمع على المنفذ 80؛ يمكن إعادة استخدام الأمر نفسه بإضافة الخيار ‎-p مع رقم العملية لتحديد الاسم الأصلي للعملية ومكان وجودها على الجهاز وهذا مفيد خصوصًا مع أباتشي.
</p>

<p style="text-align: center;">
	<img alt="02_example_lsof.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25360" data-unique="qaf6uq4yr" src="https://academy.hsoub.com/uploads/monthly_2017_11/02_example_lsof.png.2acc4d435cffe0d52238e8c8591a8e06.png"></p>

<h2>
	13. df
</h2>

<p>
	يُستعمل الأمر df لإظهار مساحة القرص المستخدمة والمتوافرة لإصلاح المشاكل المرتبطة بالتخزين. عند تشغيل تطبيق على حاوية قد تظهر رسالة خطأ تشير إلى انخفاض المساحة المتوافرة عليها، وحينئذٍ يمكن استخدام الأمر df للتأكد من صحة هذا الخطأ وأنَّه حقًا لم تعد هنالك مساحة متوافرة إذ إن مدير النظام هو المسؤول عن إدارة وتحسين مساحة القرص. توضح الصورة مساحة القرص لجميع أنظمة الملفات الموجودة.
</p>

<p style="text-align: center;">
	<img alt="03_example_df.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25361" data-unique="p5o2bqmtl" src="https://academy.hsoub.com/uploads/monthly_2017_11/03_example_df.png.5896cbbca226446f6a8b999246f77e5e.png"></p>

<p>
	الخيار ‎-h (أو ‎--human-readable) هو لإظهار الحجم بصيغة مقروءة.
</p>

<h2>
	14. du
</h2>

<p>
	يُستخدم الأمر du للحصول على معلومات تفصيليَّة عن حجم الملفات الموجودة داخل مجلد. إن أردت معرفة حجم السجلات الموجودة في المجلد ‎/var/log، على سبيل المثال، وأيُّ السجلات حجمه أكبر نفذ الأمر du مع الخيار ‎-h لتسهيل قراءة حجم الملفات والخيار ‎-s لعرض الحجم الكلي.
</p>

<pre class="ipsCode" id="ips_uid_663_20">
$ du -sh /var/log/* 
1.8M /var/log/anaconda 
384K /var/log/audit 
4.0K /var/log/boot.log 
0 /var/log/chrony 
4.0K /var/log/cron 
4.0K /var/log/maillog 
64K /var/log/messages</pre>

<p>
	نجد أنَّ المجلد anaconda هو الأكبر حجمًا من بين المجلدات الموجودة في ‎/var/log. يمكن استخدام هذا الأمر بالتزامن مع الأمر df لمعرفة كيفيَّة توزيع المساحة المستخدمة على الملفات وما هي الملفات ذات الحجم الكبير.
</p>

<h2>
	15. id
</h2>

<p>
	مهمَّة الأمر id هي عرض معلومات عن هوية مستخدم ومجموعة محدَّدة أو المستخدم الحالي والمجموعة التي ينتمي إليها.
</p>

<p>
	استخدمنا في المثال التالي الأداة Vagrant -وهي أداة للعمل ضمن بيئة افتراضيَّة- لاختبار التطبيق وعزله في بيئة تطويرية؛ بعد الدخول إلى صندوق Vagrant (البيئة الافتراضيَّة)، حاولنا تثبيت خادوم أباتشي ولكن النظام لم يسمح بتنفيذ الأمر لأنَّ تنفيذه يتطلب صلاحيات المستخدم الجذر (root)، لذا نستخدم الأمر id لمعرف هوية المستخدم الحالي.
</p>

<pre class="ipsCode" id="ips_uid_663_18">
$ yum -y install httpd 
Loaded plugins: fastestmirror 
You need to be root to perform this command. 
$ id 
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023</pre>

<p>
	ولتنفيذ الأمر السابق يجب اختيار مستخدم ذو صلاحيات أعلى.
</p>

<h2>
	16. chmod
</h2>

<p>
	قد تُصادف أحيانًا عند تشغيل تطبيق لأول مرة على حاسوبك رسالة الخطأ "الإذن مرفوض " (permission denied) لذا تأكد من الأذونات باستخدام الأمر ls.
</p>

<pre class="ipsCode" id="ips_uid_663_15">
$ ls -l 
total 4 
-rw-rw-r--. 1 vagrant vagrant 34 Jul 11 02:17 test.sh</pre>

<p>
	نلاحظ من المثال أنَّ المستخدم لا يملك إذن التنفيذ (عدم وجود x) لتشغيل التطبيق؛ نلجأ حينها إلى الأمر chmod لتغيير الأذونات وتمكين المستخدم من تشغيل التطبيق وذلك بكتابة الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_663_22">
$ chmod +x test.sh 
[vagrant@localhost ~]$ ls -l 
total 4 
-rwxrwxr-x. 1 vagrant vagrant 34 Jul 11 02:17 test.sh</pre>

<p>
	لاحظ وجود إذن التنفيذ (وجود x) ضمن أذونات الملف وإن جربنا الآن تشغيله فلن تظهر رسالة الخطأ السابقة.
</p>

<h2>
	17. dig / nslookup
</h2>

<p>
	يساعد <a href="https://academy.hsoub.com/devops/servers/%D9%85%D9%82%D8%AF%D9%91%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D9%85%D9%8F%D8%B5%D8%B7%D9%8E%D9%84%D8%AD%D8%A7%D8%AA-%D9%88%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D9%88%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D9%86%D8%B8%D8%A7%D9%85-%D8%A3%D8%B3%D9%85%D8%A7%D8%A1-%D8%A7%D9%84%D9%86%D8%B7%D8%A7%D9%82%D8%A7%D8%AA-r5/" rel="">نظام أسماء النطاقات DNS</a> على تحويل العنوان URL إلى عنوان IP، وإن لم يُحوَّل هذا العنوان فستحدث مشكلة في الاتصال. لنفترض أنَّك تريد الوصول إلى قاعدة بياناتك (mydatabase) من تطبيقك ولكنَّّك لا تستطيع إذ تظهر رسالة خطأ "لا يمكن استبيان العنوان" (cannot resolve)؛ جرب استخدام الأداة dig للبحث عن أسماء النطاقات DNS أو الأداة nslookup للاستعلام عن خواديم أسماء النطاقات لحل هذه المشكلة ومعرفة سبب عدم تمكن التطبيق من استبيان اسم نطاق قاعدة البيانات.
</p>

<pre class="ipsCode" id="ips_uid_663_25">
$ nslookup mydatabase 
Server: 10.0.2.3 
Address: 10.0.2.3#53 

** server can't find mydatabase: NXDOMAIN</pre>

<p>
	جربنا استعمال الأمر nslookup ولكن ظهرت رسالة بالخطأ نفسه أي لم يجد عنوانًا لاسم نطاق قاعدة البيانات.
</p>

<p>
	إن جربت الأمر dig فستحصل على النتيجة نفسها.
</p>

<pre class="ipsCode" id="ips_uid_663_27">
$ dig mydatabase 

; &lt;&lt;&gt;&gt; DiG 9.9.4-RedHat-9.9.4-50.el7_3.1 &lt;&lt;&gt;&gt; mydatabase 
;; global options: +cmd 
;; connection timed out; no servers could be reached</pre>

<p>
	هنالك احتمالات كثيرة تفسر سبب حدوث هذا الخطأ ليست ضمن موضوع هذه المقالة؛ تواصل مع مدير النظام المسؤول إن لم تستطع حل المشكلة ليساعدك بالبحث عن سبب المشكلة وحلها. إن لم يكن هذان الأمران موجودان على حاسوبك، فثبت الحزمة <a href="http://www.linuxfromscratch.org/blfs/view/svn/basicnet/bind-utils.html" rel="external nofollow">BIND Utilities</a>.
</p>

<h2>
	18. iptables
</h2>

<p>
	إنَّ <a href="https://academy.hsoub.com/devops/security/firewalls/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-iptables-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D9%88%D8%A3%D9%88%D8%A7%D9%85%D8%B1-%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%84%D9%84%D8%AC%D8%AF%D8%A7%D8%B1-%D8%A7%D9%84%D9%86%D8%A7%D8%B1%D9%8A-r119/" rel="">iptables</a> هو <a href="https://academy.hsoub.com/devops/security/firewalls/%D9%85%D8%A7-%D9%87%D9%88-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D8%B1-%D8%A7%D9%84%D9%86%D8%A7%D8%B1%D9%8A-%D9%88%D9%83%D9%8A%D9%81-%D9%8A%D8%B9%D9%85%D9%84%D8%9F-r114/" rel="">جدار ناري</a> موجود في أغلبية توزيعات لينكس ووظيفته هي سماح أو حجب حركة مرور البيانات الشبكيَّة؛ قد يمنع الجدار الناري تطبيقات معيَّنة من استلام أو نقل البيانات عبر الشبكة؛ إن كان أحد التطبيقات لديك يواجه صعوبةً في الوصول إلى خدمة أو موقع معيَّن فقد يكون هذا الجدار الناري هو السبب في منع حركة البيانات من الوصول إلى تلك الخدمة أو الموقع.
</p>

<p>
	لنفترض مثلًا أنَّ التطبيقات لا تتمكن من الوصول إلى الموقع opensource.com، نتأكد أولًا من الاتصال عبر الأداة curl:
</p>

<pre class="ipsCode" id="ips_uid_663_32">
$ curl -vvv opensource.com 
* About to connect() to opensource.com port 80 (#0) 
* Trying 54.204.39.132... 
* Connection timed out 
* Failed connect to opensource.com:80; Connection timed out 
* Closing connection 0 
curl: (7) Failed connect to opensource.com:80; Connection timed out</pre>

<p>
	فشِل الاتصال مع الموقع بعد انقضاء المهلة؛ قد يكون هنالك ما يمنع من الاتصال مع ذلك الموقع لذا نستعمل الأمر iptables مع الخيار ‎-S لعرض قواعد الجدار الناري.
</p>

<pre class="ipsCode" id="ips_uid_663_36">
$ iptables -S 
-P INPUT DROP 
-P FORWARD DROP 
-P OUTPUT DROP 
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT 
-A INPUT -i eth0 -p udp -m udp --sport 53 -j ACCEPT 
-A OUTPUT -p tcp -m tcp --sport 22 -j ACCEPT 
-A OUTPUT -o eth0 -p udp -m udp --dport 53 -j ACCEPT</pre>

<p>
	من الواضح أنَّ الضبط الافتراضي للقواعد الثلاث الأولى هي "تجاهل" (drop) البيانات الشبكيَّة المرسلة والمستقبلة والموجَّهة، أما القواعد الأخرى فهي "السماح" (accept) بمرور البيانات عبر خادوم <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> و DNS. استشر في هذه الحالة مدير الأنظمة إذا كان هنالك حاجة لإضافة أو تعديل قاعدة للسماح بحركة البيانات للموقع السابق. إن كان المضيف الذي تستخدمه هو بيئة محليَّة أو للاختبار المحلي فاستخدم iptables للسماح بمرور البيانات غير الضارة.
</p>

<h2>
	19. sestatus
</h2>

<p>
	توجد آلية للتحكم في الوصول على بعض توزيعات لينكس تدعى "التأمين المعزَّز في لينكس" (Security Enhanced Linux)، أو تدعى اختصارًا (<a href="https://academy.hsoub.com/certificates/redhat/rhcsa/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D8%AD%D9%83%D9%85-%D9%81%D9%8A-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-selinux-%D9%81%D9%8A-red-hat-enterprise-linux-r51/" rel="">SELinux</a>)، ومفعلة عليه (الوضع enforcing)؛ توفِّر هذه الآلية إمكانية الوصول للعمليات المشغلة حاليًا بأدنى الصلاحيات إذ يحتمل أنَّ بعض تلك العمليات ضارٌ وبذلك تُمنع من الوصول إلى الملفات المهمَّة على النظام. قد يحتاج أحد التطبيقات أحيانًا الوصول إلى ملف ما ولكنَّه لا يستطيع فتظهر رسالة خطأ بذلك؛ يجب التأكد إن كان SELinux يمنع هذا التطبيق من الوصول باستعمال الأمر tail مع grep للبحث عن الرسالة "denied" في السجل ‎/var/log/audit. قد لا يكون SELinux مفعَّلًا منذ البداية لذا من المفيد التحقق أولًا من ذلك عبر الأمر sestatus.
</p>

<pre class="ipsCode" id="ips_uid_663_55">
$ sestatus 
SELinux status:				enabled 
SELinuxfs mount:			/sys/fs/selinux 
SELinux root directory:			/etc/selinux 
Loaded policy name: 			targeted 
Current mode:				enforcing 
Mode from config file:			enforcing 
Policy MLS status:			enabled 
Policy deny_unknown status:	 	allowed 
Max kernel policy version: 		28

</pre>

<p>
	نجد من الرسالة السابقة أنَّ SELinux مفعَّل؛ يستطيع مدير النظام مساعدتك في هذا الشأن وتحديد إن كان التطبيق يستحق الوصول إلى الملفات التي يحتاجها. أَضف إلى ذلك أنَّه من المفيد تحديث SELinux دومًا على بيئتك التطويرية المحليَّة ليصبح أكثر تساهلًا.
</p>

<h2>
	20. history
</h2>

<p>
	ختامًا، وبعد تنفيذ الكثير من الأوامر سواءً للتجريب أو لإصلاح بعض المشاكل، لابد أن نشير إلى الأمر history الذي لا تكاد تخلو صدفة (shell) منه؛ مهمَّة هذا الأمر هي طبع جميع الأوامر التي استخدمتها منذ بدء استخدامك للصدفة. تكمن فائدته بتسجيل الأوامر المستخدمة لإصلاح مشكلة ما وإعادة تذكرها أو تنفيذها.
</p>

<p>
	إن نفذنا هذا الأمر فستظهر جميع الأوامر التي تعلمتها وجربتها خلال هذه المقالة:
</p>

<pre class="ipsCode" id="ips_uid_663_65">
$ history 
	1 clear 
	2 df -h 
	3 du</pre>

<p>
	إن أردت تنفيذ أحد هذه الأوامر السابقة فلن تحتاج لإعادة كتابته، فقط استخدم الرمز ! وأتبعه برقم الأمر الذي تود تنفيذه مجددًا.
</p>

<p style="text-align: center;">
	<img alt="04_example_history.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25362" data-unique="5m4r3g5kk" src="https://academy.hsoub.com/uploads/monthly_2017_11/04_example_history.png.1a7c090f1326b7da482384e9f130c6d8.png"></p>

<h2>
	الخاتمة
</h2>

<p>
	تعرَّفت على مجموعة من الأوامر الأساسيَّة التي ستزيد من خبرتك في تحليل الأعطال وإصلاحها، والتي يستخدمها الكثير من مديري الأنظمة لحل وإصلاح المشاكل التي تواجههم. التمرس على هذه الأوامر وفهمها يمنحك القدرة على التواصل مع مديري الأنظمة لحل المشاكل التي ستواجهك في المستقبل.
</p>

<p>
	ترجمة -وبتصرف- للمقال<a href="https://opensource.com/article/17/7/20-sysadmin-commands" rel="external nofollow"> 20‎ Linux commands every sysadmin should know </a>لصاحبه Rosemary Wang.
</p>
]]></description><guid isPermaLink="false">355</guid><pubDate>Sat, 14 Oct 2017 07:10:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x62B;&#x628;&#x651;&#x62A; &#x628;&#x64A;&#x626;&#x629; &#x62A;&#x637;&#x648;&#x64A;&#x631; Go &#x639;&#x644;&#x649; Centos 7</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%AB%D8%A8%D9%91%D8%AA-%D8%A8%D9%8A%D8%A6%D8%A9-%D8%AA%D8%B7%D9%88%D9%8A%D8%B1-go-%D8%B9%D9%84%D9%89-centos-7-r351/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_09/59c7e9c47a783_main(59).png.cfe62bac23dc2e2336367c751c9c95b4.png" /></p>

<p>
	تتبنّى لغة البرمجة Go مفتوحة المصدر التي تطوّرها شركة Google، والتي يُشار إليها أحيانا بـ Golang، تتبنّى مقاربة تقليلية Minimalist في تطوير البرمجيّات تسمح بكتابة برامج سهلة، موثوقة وفعّالة. يساعدك هذا الدرس في تثبيت الإصدار 1.8 من Go (الإصدار المستقرّ الأحدث حتى الساعة) على خادوم <a href="https://academy.hsoub.com/tags/centos/#elSearch_main" rel="">Centos 7</a>، وتصريف Compiling برنامج “Hello, World!” بسيط.
</p>

<h2 id="المتطلبات">
	المتطلّبات
</h2>

<p>
	يُستحسن أولا التأكد من وجود مستخدم إداري غير المستخدم الجذر على الخادوم. تمكنك معرفة كيفية ضبط مستخدم بهذه المواصفات بقراءة <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D9%8F%D8%AD%D8%B1%D9%91%D9%90%D8%B1-%D9%85%D9%84%D9%81%D9%91-sudoers-%D8%B9%D9%84%D9%89-ubuntu-%D9%88centos-r45/" rel="">هذا الدرس</a> لتعرف كيف تنشئ مستخدما بصلاحيات sudo على Centos.
</p>

<h2 id="الخطوة-الأولى-تثبيت-go">
	الخطوة الأولى: تثبيت Go
</h2>

<p>
	نذهب إلى <a href="https://golang.org/dl/" rel="external nofollow">الموقع الرسمي</a> للحصول على آخر إصدار من Go. تأكّد من تنزيل حزمة لينكس الموافقة لمعمارية 64 بت.
</p>

<p>
	نبدأ بالانتقال إلى مجلّد تمكننا الكتابة فيه:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
cd /tmp</pre>

<p>
	نستخدم الأمر <code>curl</code> ونمرّر له رابط حزمة Go الذي تحصّلنا عليه من الموقع الرسمي للغة:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs avrasm"><span class="pln">curl </span><span class="pun">-</span><span class="pln">LO https</span><span class="pun">:</span><span class="com">//storage</span><span class="hljs-preprocessor"><span class="com">.googleapis</span></span><span class="hljs-preprocessor"><span class="com">.com</span></span><span class="com">/golang/go1</span><span class="hljs-number"><span class="com">.8</span></span><span class="hljs-number"><span class="com">.3</span></span><span class="hljs-preprocessor"><span class="com">.linux</span></span><span class="com">-amd64</span><span class="hljs-preprocessor"><span class="com">.tar</span></span><span class="hljs-preprocessor"><span class="com">.gz</span></span></code></pre>

<p>
	على الرغم من أننا متأكدون من المصدر الذي نزّلنا منه الملف، إلا أنه من الجيّد التحقّق من سلامة الملفات وموثوقيّتها عند تنزيلها من الإنترنت. يوفّر موقع Go قيمة التجزئة Hash لكلّ ملف مضغوط على صفحة التنزيلات. ننفّذ الأمر التالي لحساب قيمة التجزئة الخاصّة بالملفّ الذي نزّلناه:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs avrasm"><span class="pln">shasum </span><span class="pun">-</span><span class="pln">a </span><span class="hljs-number"><span class="lit">256</span></span><span class="pln"> go1</span><span class="hljs-number"><span class="pun">.</span><span class="lit">8</span></span><span class="pun">*</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">tar</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">gz</span></span></code></pre>

<p>
	تشبه نتيجة الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs avrasm"><span class="hljs-number"><span class="lit">1862</span></span><span class="lit">f4c3d3907e59b04a757cfda0ea7aa9ef39274af99a784f5be843c80c6772</span><span class="pln">  go1</span><span class="hljs-number"><span class="pun">.</span><span class="lit">8</span></span><span class="hljs-number"><span class="lit">.3</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">linux</span></span><span class="pun">-</span><span class="pln">amd64</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">tar</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">gz</span></span></code></pre>

<p>
	قارن قيمة التجزئة التي تحصّلت عليها مع تجزئة الملف الموجودة على صفحة تنزيلات Go. توجد قيمة تجزئة لكلّ ملف على صفحة التنزيلات، لذا تأكد من التجزئة الصحيحة.
</p>

<p>
	ننتقل بعد تنزيل Go والتأكد من سلامة البيانات إلى تثبيت بيئة تصريف اللغة.
</p>

<h2 id="الخطوة-الثانية-تثبيت-go">
	الخطوة الثانية: تثبيت Go
</h2>

<p>
	يتمثّل تثبيت Go في استخراج محتويات الملفّ المضغوط وحفظها في المجلّد <code>usr/local/</code>. يحفظ <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%A3%D9%85%D8%B1-tar-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r243/" rel="">الأمر <code>tar</code></a> محتويات الملّف بعد استخراجها على المسار المُمرَّر بعد الخيار <code>C-</code>. يُستخدَم الخيار <code>x-</code> لفك ضغط الملف، <code>v-</code> لإظهار مُخرجات تفصيلية لعمل الأمر ويُحدّد <code>z-</code> الخوارزميّة المستخدمة لضغط الملف (<code>gzip</code>)؛ أما الخيار <code>f-</code> فيحدّد الملف المضغوط الذي نستخرج محتوياته:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs lasso"><span class="pln">sudo tar </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">C</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="hljs-built_in"><span class="kwd">local</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">xvzf</span></span><span class="pln"> go1</span><span class="hljs-number"><span class="pun">.</span><span class="lit">8</span></span><span class="hljs-number"><span class="lit">.3</span></span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">linux</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">amd64</span></span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">tar</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">gz</span></code></pre>

<p>
	<strong>ملحوظة:</strong> تنصح Google بوضع مجلّد Go على المسار <code>usr/local/</code>. لا يمنع وضع المجلّد على مسار آخر إمكانية استخدام اللغة، إلا أن المسار المُخصَّص يجب أن يُعرَّف ضمن متغيّر البيئة <code>GOROOT</code>. تشرح الخطوة المواليّة ضبط المسارات.
</p>

<p>
	سننشئ في ما يلي مجلّد عمل جديدا لـGo داخل المجلّد الشخصي للمستخدم، وننشئ فيه ثلاثة مجلدات فرعية <code>src</code>،<code>bin</code> و<code>pkg</code>. سيحوي المجلّد الفرعي <code>bin</code> البرامج التنفيذية الناتجة عن تصريف ملفات الشفرة البرمجية الموجودة في المجلّد <code>src</code>. لن نستخدم في هذا الدرس المجلّد <code>pkg</code> إلا أنه مفيد في المشاريع المتقدّمة إذ يخزّن الحزم وهي مجموعة من الشفرات البرمجية التي يمكن تشاركها بين البرامج.
</p>

<p>
	سنسمّي مجلّد العمل <code>projects</code>، إلا أن بإمكانك تسميته بالاسم الذي تريد. يؤدّي استخدام الخيار <code>p-</code> مع الأمر <code>mkdir</code> إلى إنشاء المجلّدات وفق الهرميّة الموجودة في المسار المُمرَّر للأمر.
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs ruby"><span class="pln">mkdir </span><span class="pun">-</span><span class="pln">p </span><span class="pun">~</span><span class="hljs-regexp"><span class="str">/projects/</span></span><span class="pun">{</span><span class="pln">bin</span><span class="pun">,</span><span class="pln">pkg</span><span class="pun">,</span><span class="pln">src</span><span class="pun">}</span></code></pre>

<p>
	يصبح Go جاهزا للعمل باكتمال هذه الخطوة، إلا أن استخدامه يتطلّب ذكر مسار التثبيت كاملا في سطر الأوامر. يمكن أن نجعل الاستخدام أكثر سهولة بضبط بضعة مسارات، وهو ما سنفعله في الخطوة التالية.
</p>

<h2 id="الخطوة-الثالثة-ضبط-مسارات-go">
	الخطوة الثالثة: ضبط مسارات Go
</h2>

<p>
	سنحتاج لإدراج المسار الذي ثبّتنا عليها Go إلى متغيّر البيئة <code>PATH$</code> حتى يمكننا تنفيذه بنفس طريقة تنفيذ أي أمر في الطرفية: ذكر اسم الأمر فقط، دون المسار الكامل. بما أن Go مثبَّت في مجلّد يستخدمه نظام التشغيل فسنضبُط Go ليكون متاحا لجميع المستخدمين.
</p>

<p>
	أنشئ سكريبت باسم <code>path.sh</code> على المسار <code>etc/profile.d/</code> باستخدام محرّر النصوص <code>vi</code>:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs avrasm"><span class="pln">sudo vi </span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln">profile</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">d</span></span><span class="pun">/</span><span class="pln">path</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">sh</span></span></code></pre>

<p>
	أضف السطر التالي إلى آخر الملف ثم احفظ الملف وأغلقه:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs ruby"><span class="kwd">export</span><span class="pln"> </span><span class="hljs-constant"><span class="pln">PATH</span></span><span class="pun">=</span><span class="hljs-variable"><span class="pln">$PATH</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/usr/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">go</span><span class="pun">/</span><span class="pln">bin</span></span></code></pre>

<p>
	<strong>تنبيه:</strong> عدّل المسار بما يُناسب إن كنت قد اخترت مكانا مختلفا لتثبيت Go.
</p>

<p>
	نعرّف أيضا قيمتيْ المتغيّريْن <code>GOPATH</code> و<code>GOBIN</code>في ملّف المستخدم <code>bash_profile.</code> للإشارة إلى مجلّد العمل الذي أنشأناه في الخطوة السابقة. يحدّد المتغيّر <code>GOPATH</code> مكان ملفات الشفرة البرمجية بينما يحدّد المتغيّر <code>GOBIN</code> المجلّد الذي يجب أن توضع فيه الملفات التنفيذية بعد تصريف الشفرات البرمجية.
</p>

<p>
	نفتح الملف <code>bash_profile.</code>:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs avrasm"><span class="pln">vi </span><span class="pun">~/</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">bash</span></span><span class="pln">_profile</span></code></pre>

<p>
	نضيف السطريْن التاليّيْن إلى نهاية الملف:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs bash"><span class="hljs-keyword"><span class="kwd">export</span></span><span class="pln"> GOBIN</span><span class="pun">=</span><span class="hljs-string"><span class="str">"</span><span class="hljs-variable"><span class="str">$HOME</span></span><span class="str">/projects/bin"</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">export</span></span><span class="pln"> GOPATH</span><span class="pun">=</span><span class="hljs-string"><span class="str">"</span><span class="hljs-variable"><span class="str">$HOME</span></span><span class="str">/projects/src"</span></span>
</code></pre>

<p>
	<strong>تنبيه:</strong> إن كان Go مثبّتا على مسار غير المسار المنصوح به (<code>usr/local/</code>) فيجب أن تعرّف قيمة المتغيّر <code>GOROOT</code> في الملفّ <code>bash_profile.</code> إلى جانب المتغيّريْن <code>GOBIN</code> و<code>GOPATH</code>:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs bash"><span class="hljs-keyword"><span class="kwd">export</span></span><span class="pln"> GOROOT</span><span class="pun">=</span><span class="hljs-string"><span class="str">"/path/to/go"</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">export</span></span><span class="pln"> GOBIN</span><span class="pun">=</span><span class="hljs-string"><span class="str">"</span><span class="hljs-variable"><span class="str">$HOME</span></span><span class="str">/projects/bin"</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">export</span></span><span class="pln"> GOPATH</span><span class="pun">=</span><span class="hljs-string"><span class="str">"</span><span class="hljs-variable"><span class="str">$HOME</span></span><span class="str">/projects/src"</span></span></code></pre>

<p>
	حيث <code>path/to/go/</code> مسار تثبيت Go.
</p>

<p>
	ننفّذ الأمر <code>source</code> لاعتماد التغييرات على الملفات التي عدّلناها وإعادة تحميلها لجلسة الطرفية الحالية:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">source</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln">profile </span><span class="pun">&amp;&amp;</span><span class="pln"> </span><span class="hljs-built_in"><span class="pln">source</span></span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">bash_profile</span></code></pre>

<p>
	يجب أن يكون كلّ شيء جاهزا الآن، وهو ما سنتأكّد منه في الخطوة التالية.
</p>

<h2 id="الخطوة-الرابعة-كتابة-برنامج-go-واختباره">
	الخطوة الرابعة: كتابة برنامج Go واختباره
</h2>

<p>
	نهدف من هذه الخطوة إلى التأكد من أن بيئة Go جاهزة للعمل على جهازنا. نبدأ بإنشاء ملفّ جديد لنضع فيه أول شفرة برمجيّة نكتبها:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs ruby"><span class="pln">vi </span><span class="pun">~</span><span class="hljs-regexp"><span class="str">/projects/</span><span class="pln">src</span></span><span class="hljs-regexp"><span class="pun">/</span><span class="pln">hello</span><span class="pun">.</span><span class="pln">go</span></span></code></pre>

<p>
	تستخدم شفرة Go أدناه حزمة <code>main</code>، تستورد مكتبة <code>fmt</code> لدوالّ الإدخال والإخراج وتضبُط دالة جديدة لطباعة الجملة <code>!Hello, World</code>.
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs go"><span class="hljs-keyword"><span class="kwd">package</span></span><span class="pln"> main

</span><span class="hljs-keyword"><span class="kwd">import</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"fmt"</span></span><span class="pln">

</span><span class="hljs-keyword"><span class="pln">func</span></span><span class="pln"> main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    fmt</span><span class="pun">.</span><span class="typ">Printf</span><span class="pun">(</span><span class="hljs-string"><span class="str">"Hello, World!\n"</span></span><span class="pun">)</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	احفظ الملف ثم أغلقه.
</p>

<p>
	ثم نصرّف الشفرة البرمجية بالأمر <code>go install</code>:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs go"><span class="hljs-keyword"><span class="pln">go</span></span><span class="pln"> install $GOPATH</span><span class="pun">/</span><span class="pln">hello</span><span class="pun">.</span><span class="hljs-keyword"><span class="pln">go</span></span></code></pre>

<p>
	نحن الآن جاهزون لتشغيل البرنامج:
</p>

<pre class="ipsCode" id="ips_uid_9811_7">
<code class="hljs bash"><span class="hljs-variable"><span class="pln">$GOBIN</span></span><span class="pun">/</span><span class="pln">hello</span></code></pre>

<p>
	إن كان كل شيء على ما يُرام فستظهر رسالة <code>Hello, World!</code> بعد تشغيل البرنامج.
</p>

<p>
	نتأكد بتنفيذ برنامج <code>Hello, World!</code> السابق من أن بيئة Go مثبّتة وجاهزة للاستخدام. تستخدم برامج Go عادة مكتبات برمجية وحزما خارجية. راجع مقالات <a href="https://academy.hsoub.com/programming/go/" rel="">البرمجة بلغة Go</a> للمزيد عن كيفية كتابة البرامج بهذه اللغة.
</p>

<p>
	ترجمة - بتصرّف - للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-install-go-1-7-on-centos-7" rel="external nofollow">How To Install Go 1.7 on CentOS 7</a> لصاحبه Michael Lenardson.
</p>
]]></description><guid isPermaLink="false">351</guid><pubDate>Sun, 24 Sep 2017 17:23:43 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x62B;&#x628;&#x651;&#x62A; &#x644;&#x63A;&#x629; Go 1.7 &#x639;&#x644;&#x649; &#x62F;&#x628;&#x64A;&#x627;&#x646; 8</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%AB%D8%A8%D9%91%D8%AA-%D9%84%D8%BA%D8%A9-go-17-%D8%B9%D9%84%D9%89-%D8%AF%D8%A8%D9%8A%D8%A7%D9%86-8-r350/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_09/59c64f6ca8628_main(51).png.527482c462ddc0b7fb73ff4c42fb4848.png" /></p>

<p>
	<a href="https://academy.hsoub.com/programming/go/" rel="">لغة Go</a> (والتي يشار إليها golang أيضًا) هي لغة برمجة عصرية مفتوحة المصدر طورتها Google، وازداد انتشارها في كثير من الاستخدامات، وهي تنتهج منهج التبسيط (minimalist) في التطوير وتُسهِّل بناء برمجيات عملية ذات كفاءة عالية.<br>
	سيشرح هذا الدرس كيفية تحميل وتثبيت Go 1.7، إضافةً إلى شرح تصريف (compile) وتنفيذ برنامج بسيط («!Hello World») على خادوم دبيان 8.
</p>

<h2 id="المتطلبات-المسبقة">
	المتطلبات المسبقة
</h2>

<p>
	يفترض هذا الدرس أنَّ لديك وصولًا إلى خادوم دبيان 8 مضبوط فيه حساب مستخدم ليس جذرًا لكنه يمتلك امتيازات الجذر عبر الأمر <code>sudo</code>.
</p>

<h2 id="الخطوة-الأولى-تنزيل-حزمة-لغة-go">
	الخطوة الأولى: تحميل حزمة لغة Go
</h2>

<p>
	سنبدأ بتحميل حزمة Go على خادومنا من الموقع الرسمي.<br>
	اذهب إلى <a href="https://golang.org/dl/" rel="external nofollow">صفحة تنزيل لغة Go الرسمية</a> وابحث عن رابط URL لأرشيف النسخة الحالية من النسخة الثنائية (binary) من اللغة. احرص على أن تنسخ رابط آخر نسخة متوافرة ومتوافقة مع معمارية 64 بت.<br>
	استعمل الأمر <code>curl</code> من مجلد المنزل لتحميل الأرشيف:
</p>

<pre class="ipsCode" id="ips_uid_5961_10">
curl -O https://storage.googleapis.com/golang/go1.7.4.linux-amd64.tar.gz</pre>

<p>
	وصحيحٌ أننا حمّلنا الملف من مصدر موثوق، إلا أنَّه من الأفضل التحقق من سلامة الملفات التي نحمّلها عبر الإنترنت، وهذا يعني أننا سنضمن أنَّ الملف لم يُعدَّل أو يتلاعب به أو يعطَب أثناء عملية التحميل.<br>
	الأمر <code>sha256sum</code> يُظهِر رمزًا فريدًا من 256 بت:
</p>

<pre class="ipsCode" id="ips_uid_5961_8">
sha256sum go1.7*.tar.gz</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_5961_13">
47fda42e46b4c3ec93fa5d4d4cc6a748aa3f9411a2a2b7e08e3a6d80d753ec8b  go1.7.4.linux-amd64.tar.gz</pre>

<p>
	قارن الرمز الظاهر في ناتج الأمر السابق مع القيمة الموجودة في صفحة <a href="https://golang.org/dl/" rel="external nofollow">تحميل Go</a>، إذا وجدتهما متطابقين فهذا يعني أنَّ عملية التحميل قد نجحت.<br>
	لنحاول تثبيت لغة Go بعد أن تحققنا من سلامة الملف.
</p>

<h2 id="الخطوة-الثانية-تثبيت-لغة-go">
	الخطوة الثانية: تثبيت لغة Go
</h2>

<p>
	سنستخدم الأمر <code>tar</code> لاستخراج محتويات الأرشيف، إذ يطلب الخيار <code>x</code> من الأمر <code>tar</code> أن يستخرج محتويات الملف، والخيار <code>v</code> أن يعرض مخرجات (والتي هي قائمة بالملفات التي ستُستخرَج)، أما الخيار <code>f</code> فيطلب من الأمر <code>tar</code> قراءة ملف الأرشيف المُحدَّد:
</p>

<pre class="ipsCode" id="ips_uid_5961_15">
tar xvf go1.7.4.linux-amd64.tar.gz</pre>

<p>
	يجب أن يُنشَأ مجلدٌ باسم <code>go</code> في مجلد العمل الحالي (وهو مجلد Home)، عليك الآن تبديل المستخدم المالك والمجموعة المالكة لمجلد <code>go</code> إلى الجذر، ثم نقله إلى مجلد <code>‎/usr/local</code>:
</p>

<pre class="ipsCode" id="ips_uid_5961_17">
sudo chown -R root:root ./go
sudo mv go /usr/local</pre>

<p>
	<strong>ملاحظة:</strong> على الرغم من أنَّ المسار <code>‎/usr/local/go</code> هو المسار المنصوح به رسميًا، لكن بعض المستخدمين يفضلون استخدام مسارات مختلفة.<br>
	عند هذه النقطة يجب تحديد مسار التثبيت عند استدعاء لغة Go من سطر الأوامر، ولجعل التعامل مع Go أسهل قليلًا ، سنضبط بعض المسارات.
</p>

<h2 id="الخطوة-الثالثة-ضبط-مسارات-go">
	الخطوة الثالثة: ضبط مسارات Go
</h2>

<p>
	سنضبط في هذه الخطوة بعض المسارات في البيئة (environment) عندك.<br>
	لنضبط أولًا قيمة مجلد الجذر للغة Go، الذي يخبر Go أين عليها أن تبحث عن ملفاتها:
</p>

<pre class="ipsCode" id="ips_uid_5961_19">
sudo nano ~/.profile</pre>

<p>
	أضف السطرين الآتيين في نهاية الملف:
</p>

<pre class="ipsCode" id="ips_uid_5961_21">
export GOPATH=$HOME/work
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin</pre>

<p>
	إذا اخترت تثبيت Go في مجلد آخر، فأضف الأسطر الآتية بدلًا مما سبق، فلو ثبتنا Go في مجلد Home على سبيل المثال، فسنضيف:
</p>

<pre class="ipsCode" id="ips_uid_5961_23">
export GOROOT=$HOME/go
export GOPATH=$HOME/work
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin</pre>

<p>
	بعد تعديل الملف بما هو مناسب، احفظ الملف وأغلق المحرر، ثم أعد قراءة ملف <code>‎.profile</code> في جلسة bash الحالية:
</p>

<pre class="ipsCode" id="ips_uid_5961_25">
source ~/.profile</pre>

<p>
	لقد أنهينا تثبيت Go، لذا لنتأكد من ذلك بكتابة برنامج قصير.
</p>

<h2 id="الخطوة-الرابعة-تجربة-go">
	الخطوة الرابعة: تجربة Go
</h2>

<p>
	بعد أن ثبتنا Go وضبطنا المسارات في خادومنا، يمكننا تجربتها للتأكد من أنها تعمل كما هو متوقع.<br>
	أنشِئ مجلدًا جديدًا لبيئة عمل Go، وهو المكان الذي ستبني فيها Go ملفاتها:
</p>

<pre class="ipsCode" id="ips_uid_5961_27">
mkdir $HOME/work</pre>

<p>
	ثم أنشِئ هيكلة المجلدات اللازمة في ذاك المجلد لإنشاء برنامج بسيط، وسنستخدم <code>my_project</code> اسمًا لمشروعنا في هذا المثال:
</p>

<pre class="ipsCode" id="ips_uid_5961_29">
mkdir -p work/src/my_project/hello</pre>

<p>
	يمكنك الآن إنشاء ملف «Hello, World!‎» بلغة Go:
</p>

<pre class="ipsCode" id="ips_uid_5961_31">
nano ~/work/src/my_project/hello/hello.go</pre>

<p>
	ألصق الشيفرة الآتية داخل محررك، والذي يستخدم حزمة <code>main</code> في لغة go، ثم يستورد المكوِّن <code>fmt</code>، ثم يُنشِئ دالةً جديدةً لطباعة <code>Hello, World!‎</code> عند تشغيله:
</p>

<pre class="ipsCode" id="ips_uid_5961_33">
package main

import "fmt"

func main() {
    fmt.Printf("Hello, World!\n")
}</pre>

<p>
	سيطبع البرنامج السابق العبارة «Hello, World!‎» إلى الطرفية إذا عَمِلَ دون مشاكل، مما يشير إلى إمكانية تصريف تطبيقات Go بنجاح.<br>
	احفظ الملف وأغلق المحرر، ثم صرِّف (compile) الملف بتنفيذ التعليمة <code>install</code> التابعة للغة Go:
</p>

<pre class="ipsCode" id="ips_uid_5961_35">
go install my_project/hello</pre>

<p>
	يمكنك تشغيل الملف بعد التصريف بتنفيذ الأمر:
</p>

<pre class="ipsCode" id="ips_uid_5961_37">
hello</pre>

<p>
	إذا شاهدت المخرجات الآتية فاعلم أنَّ لغة Go مثبتة بشكل صحيح:
</p>

<pre class="ipsCode" id="ips_uid_5961_39">
Hello, World!</pre>

<p>
	يمكنك معرفة مكان وجود الملف التنفيذي <code>hello</code> في نظامك باستخدام الأمر <code>which</code>:
</p>

<pre class="ipsCode" id="ips_uid_5961_41">
which hello</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_5961_43">
/home/user/work/bin/hello</pre>

<p>
	تأكدنا من أنَّ بيئة تطوير Go تعمل بسلاسة بعد تشغيلنا لبرنامج Hello World البسيط السابق.
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	بعد تحميل وتثبيت آخر حزمة Go وضبط المسارات الخاصة بها، أصبح نظامك جاهزًا لتطوير تطبيقات Go.<br>
	لاحظ أنَّ التطبيقات الاعتيادية تستخدم مكتبات وحزم أخرى، ولتعلم المزيد من المعلومات حول تلك المكونات، انظر إلى صفحة <a href="https://golang.org/doc/code.html" rel="external nofollow">How to Write Go Code</a> في الدليل الرسمي.
</p>

<p>
	ترجمة –وبتصرّف– للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-install-go-1-7-on-debian-8" rel="external nofollow">How To Install Go 1.7 on Debian 8</a> لصاحبته Lisa Tagliaferri
</p>
]]></description><guid isPermaLink="false">350</guid><pubDate>Sat, 23 Sep 2017 12:12:29 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x62D;&#x644;&#x651; &#x645;&#x634;&#x643;&#x644;&#x629; "&#x62E;&#x637;&#x623; &#x641;&#x64A; &#x625;&#x646;&#x634;&#x627;&#x621; &#x627;&#x62A;&#x635;&#x627;&#x644; &#x628;&#x642;&#x627;&#x639;&#x62F;&#x629; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A;" &#x641;&#x64A; &#x648;&#x648;&#x631;&#x62F;&#x628;&#x631;&#x64A;&#x633;</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%AD%D9%84%D9%91-%D9%85%D8%B4%D9%83%D9%84%D8%A9-%D8%AE%D8%B7%D8%A3-%D9%81%D9%8A-%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D9%82%D8%A7%D8%B9%D8%AF%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-%D9%88%D9%88%D8%B1%D8%AF%D8%A8%D8%B1%D9%8A%D8%B3-r348/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_09/59bc1c58ce594_main(39).png.cdf5efdf1e49db202b3746221dc89d95.png" /></p>

<p>
	برمجية ووردبريس هي واحدة من أشهر أنظمة إدارة المحتوى مفتوحة المصدر في العالم، وصحيحٌ أنَّ غرضها الأساسي هو إنشاء مدونات، لكنها تطورت على مرّ السنين لتصبح منصةً مرنةً لإنشاء مواقع الويب، ولا نستطيع أن ننكر مدى ثباتها وموثوقيتها التي تطورت خلال خمسة عشر عامًا، لكن ما تزال بعض المشكلات تظهر بين الفينة والأخرى.<br>
	إذا حاولت فتح موقعك الذي يعتمد على ووردبريس ورأيت رسالةً تُشير إلى خطأ في قواعد البيانات “خطأ في إنشاء اتصال بقاعدة البيانات” (Error Establishing Database Connection)، فمن المرجح أن يكون السبب بين القائمة الآتية:
</p>

<ul>
<li>
		انهارت قاعدة البيانات، ربما بسبب نفاد الذاكرة المتاحة للخادوم
	</li>
	<li>
		معلومات الوصول إلى قاعدة البيانات الموجودة في ضبط ووردبريس غير صحيحة
	</li>
	<li>
		حدث ضرر في جداول قاعدة بيانات ووردبريس
	</li>
</ul>
<p>
	لنناقش المشاكل السابقة كلًّا على حدة لنعرف إن كان هو السبب فيما أصاب موقعك، مع ذكر طريقة حلها.
</p>

<h2 id="المتطلبات-المسبقة">
	المتطلبات المسبقة
</h2>

<p>
	يفترض هذا الدرس:
</p>

<ul>
<li>
		أنَّك تستعمل ووردبريس على خادوم يمكنك الوصول إلى سطر أوامر وتستطيع تشغيل الأوامر فيه بامتيازات الجذر عبر الأداة <code>sudo</code>.
	</li>
	<li>
		تعمل قاعدة البيانات على خادوم ووردبريس نفسه (وهذا شائع في مواقع ووردبريس المستضافة ذاتيًا، لكنه ليس شائعًا في مواقع ووردبريس المستضافة على استضافة مشتركة).
	</li>
	<li>
		أنَّك تعرف اسم المستخدم الذي يملك وصولًا إلى قاعدة البيانات مع كلمة مروره، واسم قاعدة البيانات الخاصة بورردبريس. يجب أن توفِّر هذه المعلومات عند ضبطك لبرمجية ووردبريس ضبطًا مبدئيًا.
	</li>
</ul>
<h2 id="الخطوة-الأولى-التحقق-من-الذاكرة-المتاحة-على-الخادوم">
	الخطوة الأولى: التحقق من الذاكرة المتاحة على الخادوم
</h2>

<p>
	أوّل خطوة لمعرفة سبب المشكلة هي تسجيل الدخول إلى الخادوم لمعرفة إذا كان سليمًا وأنَّ خدمة MySQL تعمل دون مشاكل.<br>
	سجِّل دخولك إلى الخادوم عبر <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، وتذكر أن تضع اسم المستخدم واسم النطاق الخاصين بك في الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs ruby"><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> sammy</span><span class="hljs-variable"><span class="pln">@your_server_ip</span></span></code></pre>

<p>
	ملاحظة: إذا كنتَ متأكدًا أنَّ معلومات الاتصال الخاصة بك صحيحة لكنك تواجه مشاكل في تسجيل الدخول، فقد يكون السبب هو نفاد الذاكرة في خادومك أو أنَّه تحت حِملٍ شديد؛ وقد يكون ذلك بسبب كمية كبيرة من البيانات المُرسَلة إلى موقعك، وهذا يُفسِّر سبب الخطأ الذي حدث في ووردبريس… قد تحتاج إلى إعادة تشغيل خادومك قبل أن تتمكن من تسجيل الدخول إليه.<br>
	بعد أن سجلنا دخولنا بنجاح إلى الخادوم، فيمكننا التأكد أنَّ قواعد MySQL تعمل دون مشاكل:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
sudo netstat -plt</pre>

<p>
	يعرض الأمر <code>netstat</code> معلوماتٍ حول الاتصالات الشبكية في نظامنا، وطلبنا من الأمر السابق أسماء البرامج <code>‎-p</code> التي تستمع إلى الاتصالات <code>‎-l</code> على مقابس TCP ‏<code>‎-t</code>؛ عليك الآن البحث عن السطر الذي تُذكر خدمة <code>mysqld</code> فيه:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs ruby"><span class="hljs-constant"><span class="typ">Active</span></span><span class="pln"> </span><span class="hljs-constant"><span class="typ">Internet</span></span><span class="pln"> connections </span><span class="pun">(</span><span class="pln">only servers</span><span class="pun">)</span><span class="pln">
</span><span class="hljs-constant"><span class="typ">Proto</span></span><span class="pln"> </span><span class="hljs-constant"><span class="typ">Recv</span></span><span class="pun">-</span><span class="hljs-constant"><span class="pln">Q</span></span><span class="pln"> </span><span class="hljs-constant"><span class="typ">Send</span></span><span class="pun">-</span><span class="hljs-constant"><span class="pln">Q</span></span><span class="pln"> </span><span class="hljs-constant"><span class="typ">Local</span></span><span class="pln"> </span><span class="hljs-constant"><span class="typ">Address</span></span><span class="pln">           </span><span class="hljs-constant"><span class="typ">Foreign</span></span><span class="pln"> </span><span class="hljs-constant"><span class="typ">Address</span></span><span class="pln">         </span><span class="hljs-constant"><span class="typ">State</span></span><span class="pln">       </span><span class="hljs-constant"><span class="pln"><abbr title="Process IDentifier | معرّف العملية أو البرنامج">PID</abbr></span></span><span class="pun">/</span><span class="hljs-constant"><span class="typ">Program</span></span><span class="pln"> name
tcp        </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="hljs-symbol"><span class="pln">localhost</span><span class="pun">:</span></span><span class="pln">mysql         </span><span class="pun">*</span><span class="hljs-symbol"><span class="pun">:*</span></span><span class="pln">                     </span><span class="hljs-constant"><span class="pln">LISTEN</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">1958</span></span><span class="pun">/</span><span class="pln">mysqld
tcp        </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="pun">*</span><span class="hljs-symbol"><span class="pun">:</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span></span><span class="pln">                   </span><span class="pun">*</span><span class="hljs-symbol"><span class="pun">:*</span></span><span class="pln">                     </span><span class="hljs-constant"><span class="pln">LISTEN</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">2205</span></span><span class="pun">/</span><span class="pln">sshd
tcp        </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="hljs-symbol"><span class="pln">localhost</span><span class="pun">:</span></span><span class="pln">smtp          </span><span class="pun">*</span><span class="hljs-symbol"><span class="pun">:*</span></span><span class="pln">                     </span><span class="hljs-constant"><span class="pln">LISTEN</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">2361</span></span><span class="pun">/</span><span class="pln">master
tcp6       </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="pun">[</span><span class="hljs-symbol"><span class="pun">:</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">]</span><span class="hljs-symbol"><span class="pun">:</span><span class="pln">http</span></span><span class="pln">               </span><span class="pun">[</span><span class="hljs-symbol"><span class="pun">:</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">]</span><span class="hljs-symbol"><span class="pun">:*</span></span><span class="pln">                  </span><span class="hljs-constant"><span class="pln">LISTEN</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">16091</span></span><span class="pun">/</span><span class="pln">apache2
tcp6       </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> </span><span class="pun">[</span><span class="hljs-symbol"><span class="pun">:</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">]</span><span class="hljs-symbol"><span class="pun">:</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span></span><span class="pln">                </span><span class="pun">[</span><span class="hljs-symbol"><span class="pun">:</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">]</span><span class="hljs-symbol"><span class="pun">:*</span></span><span class="pln">                  </span><span class="hljs-constant"><span class="pln">LISTEN</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">2205</span></span><span class="pun">/</span><span class="pln">sshd
tcp6       </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> ip6</span><span class="pun">-</span><span class="hljs-symbol"><span class="pln">localhost</span><span class="pun">:</span></span><span class="pln">smtp      </span><span class="pun">[</span><span class="hljs-symbol"><span class="pun">:</span></span><span class="hljs-symbol"><span class="pun">:</span></span><span class="pun">]</span><span class="hljs-symbol"><span class="pun">:*</span></span><span class="pln">                  </span><span class="hljs-constant"><span class="pln">LISTEN</span></span><span class="pln">      </span><span class="hljs-number"><span class="lit">2361</span></span><span class="pun">/</span><span class="pln">master</span></code></pre>

<p>
	إذا كانت مخرجات الأمر السابق عندك مشابهةً لما سبق، فهذا يعني أنَّ خادوم MySQL يعمل ويستمع إلى الاتصالات القادمة؛ أما إذا لم ترَ خدمة MySQL مذكورةً في الناتج، فجرِّب تشغيلها يدويًا، وذلك باستعمال أمرٍ شبيهٍ بالأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> systemctl start mysql</span></code></pre>

<p>
	لاحظ أنَّ بعض توزيعات لينكس (وأشهرها CentOS) تستعمل <code>mysqld</code> بدلًا من <code>mysql</code> للإشارة إلى اسم الخدمة؛ لذا ضع الكلمة الملائمة لنظامك الذي تستعمله.<br>
	يجب أن تبدأ خدمة MySQL الآن، وأعد تشغيل أمر <code>netstat</code> السابق للتأكد من ذلك، وابحث عن السطر الذي يحتوي على اسم خدمة MySQL.<br>
	تحتاج قواعد بيانات MySQL وبرمجية ووردبريس إلى قدرٍ لا بأس به من الذاكرة لكي تعمل عملًا سليمًا؛ وإذا انهارت قواعد البيانات بسبب نفاد الذاكرة، فيجب أن نرى دليلًا على ذلك في سجل الأخطاء. لنلقِ نظرة:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs lasso"><span class="pln">zgrep </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">a</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"allocate memory"</span></span><span class="pln"> </span><span class="pun">/</span><span class="hljs-built_in"><span class="kwd">var</span></span><span class="pun">/</span><span class="hljs-keyword"><span class="pln">log</span></span><span class="pun">/</span><span class="pln">mysql</span><span class="pun">/</span><span class="pln">error</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="hljs-keyword"><span class="pln">log</span></span><span class="hljs-subst"><span class="pun">*</span></span></code></pre>

<p>
	الأمر <code>zgrep</code> سيبحث في ملفات السجل، بما فيها ملفات السجل القديمة والتي ضُغِطَت لتوفير المساحة التخزينية؛ وحددنا في الأمر السابق أننا نبحث في أي سطر يحتوي على العبارة <code>allocate memory</code> في أي ملف <code>error.log*‎</code> موجود في مجلد <code>‎/var/log/mysql/‎</code>:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs css"><span class="lit">2017</span><span class="hljs-tag"><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">11T17</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">38</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">22</span></span><span class="hljs-class"><span class="lit">.604644Z</span></span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="hljs-attr_selector"><span class="pun">[</span><span class="pln">ERROR</span><span class="pun">]</span></span><span class="pln"> </span><span class="hljs-tag"><span class="typ">InnoDB</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-tag"><span class="typ">Cannot</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">allocate</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">memory</span></span><span class="pln"> </span><span class="hljs-tag"><span class="kwd">for</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">the</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">buffer</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">pool</span></span></code></pre>

<p>
	إذا رأيتَ سطرًا أو أكثر يشبه السطر السابق فهذا يعني أنَّ خادوم MySQL قد انهار بسبب عدم كفاية الذاكرة؛ وإذا وجدتَ سطرًا وحيدًا فقط فهذا يعني أنَّ الانهيار عَرَضي بسبب كمية مؤقتة كبيرة من البيانات، أما إذا كانت هنالك عدِّة أسطر تحوي الخطأ نفسه، فهذا يعني أنَّ الذاكرة الحالية لا تكفي خادومك.<br>
	في كلا الحالتين السابقتين، الحل العملي لهذه المشكلة هو الانتقال إلى خادومٍ تتوافر فيه ذاكرة أكثر، والأمر بسيطٌ جدًا إذا كان خادومك مستضافًا على خدمةٍ سحابية، إذ تستطيع ترقية الخادوم دون انقطاع الخدمة لوقتٍ طويل.<br>
	إذا لم تجد أيّة مخرجات بعد تنفيذ أمر <code>zgrep</code> السابق، فهذا يعني أنَّ الذاكرة تكفي خادومك، وإن بقي موقعك يُظهِر رسالة الخطأ، فانتقل إلى الخطوة التالية التي نلقي فيها نظرةً على ضبط ووردبريس ونتأكد أنَّ معلومات الدخول إلى قاعدة MySQL صحيحة.
</p>

<h2 id="الخطوة-الثانية-التحقق-من-معلومات-الدخول-إلى-قاعدة-البيانات">
	الخطوة الثانية: التحقق من معلومات الدخول إلى قاعدة البيانات
</h2>

<p>
	إذا نقلتَ موقع ووردبريس إلى خادوم جديد أو إلى استضافة أخرى، فقد تحتاج إلى تحديث معلومات الاتصال بقاعدة البيانات، وهذه المعلومات مخزنة في ملف PHP على الخادوم باسم <code>wp-config.php</code>.<br>
	لنعثر بدايةً على ملف <code>wp-config.php</code>:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> find </span><span class="pun">/</span><span class="pln"> </span><span class="pun">-</span><span class="pln">name </span><span class="hljs-string"><span class="str">"wp-config.php"</span></span></code></pre>

<p>
	الأمر السابق يبحث في كل النظام (بدءًا من المجلد الجذر <code>/</code>) عن أي ملف باسم <code>wp-config.php</code>، ثم سيعرض المسار الكامل للملف إن عُثِرَ عليه:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs lasso"><span class="str">/</span><span class="hljs-built_in"><span class="str">var</span></span><span class="str">/</span><span class="pln">www</span><span class="pun">/</span><span class="pln">html</span><span class="pun">/</span><span class="pln">wp</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">config</span></span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">php</span></code></pre>

<p>
	<strong>ملاحظة</strong>: إذا كنتَ تعلم مكان تثبيت برمجية ووردبريس، فيمكنك الانتقال إلى مسار تثبيتها مباشرةً وتخطي الخطوة السابقة لأنها تستهلك بعض الوقت.<br>
	استعمل محرِّرك النصي المفضل لتعديل ملف الضبط، سنستعمل محرر <code>nano</code> في الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs lasso"><span class="pln">sudo nano </span><span class="pun">/</span><span class="hljs-built_in"><span class="kwd">var</span></span><span class="pun">/</span><span class="pln">www</span><span class="pun">/</span><span class="pln">html</span><span class="pun">/</span><span class="pln">wp</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">config</span></span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">php</span></code></pre>

<p>
	ستشاهد أمامك ملفًا نصيًا مليئًا بخيارات الضبط مع بعض التعليقات التي تشرحها. لكنك ستجد قسمًا (في بداية الملف عادةً) فيه معلومات الاتصال إلى قاعدة البيانات:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs java"><span class="hljs-javadoc"><span class="com">/** The name of the database for WordPress */</span></span><span class="pln">
define</span><span class="pun">(</span><span class="hljs-string"><span class="str">'DB_NAME'</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">'database_name'</span></span><span class="pun">);</span><span class="pln">

</span><span class="hljs-javadoc"><span class="com">/** MySQL database username */</span></span><span class="pln">
define</span><span class="pun">(</span><span class="hljs-string"><span class="str">'DB_USER'</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">'database_username'</span></span><span class="pun">);</span><span class="pln">

</span><span class="hljs-javadoc"><span class="com">/** MySQL database password */</span></span><span class="pln">
define</span><span class="pun">(</span><span class="hljs-string"><span class="str">'DB_PASSWORD'</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">'database_password'</span></span><span class="pun">);</span></code></pre>

<p>
	تأكد أن القيم الثلاث السابقة صحيحة بناءً على معلومات الاتصال المسجلة عندك؛ وإذا لم تكن صحيحةً فحدِّثها وفقًا لما تراه مناسبًا، ثم احفظ الملف واخرج من المحرر (بضغط Ctrl+o للحفظ ثم Ctrl+x للخروج، وذلك إذا كنتَ تستعمل محرر <code>nano</code>).<br>
	حتى لو بدت لك معلومات الاتصال بقاعدة البيانات صحيحةً، فمن المفيد تجربة الاتصال إلى قاعدة البيانات من سطر الأوامر ليطمئن قلبك. انسخ المعلومات المذكورة في ملف الضبط السابق واستعملها في هذا الأمر:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs lasso"><span class="pln">mysqlshow </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">u</span></span><span class="pln"> database_username </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">p</span></span></code></pre>

<p>
	عندما يُطلَب منك إدخال كلمة مرور فألصقها واضغط على زر Enter، وإن ظهر لك خطأ Access denied فهذا يعني أنَّ اسم المستخدم أو كلمة المرور خطأ، وإذا كانا صحيحين فسيعرض الأمر <code>mysqlshow</code> جميع قواعد البيانات التي يملك المستخدم وصولًا إليها:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs asciidoc"><span class="hljs-code"><span class="pun">+--------------------+</span></span><span class="pln">
</span><span class="hljs-header"><span class="pun">|</span><span class="pln">     </span><span class="typ">Databases</span><span class="pln">      </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+--------------------+</span></span><span class="pln">
</span><span class="pun">|</span><span class="pln"> information</span><span class="hljs-emphasis"><span class="pln">_schema </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> database_</span></span><span class="pln">name      </span><span class="pun">|</span><span class="pln">
</span><span class="hljs-code"><span class="pun">+--------------------+</span></span></code></pre>

<p>
	تأكد أنَّ اسم إحدى قواعد البيانات يطابق تمامًا الاسم المذكور في ملف ضبط ووردبريس؛ وعندئذٍ ستعلم أنَّ ضبطك صحيح وأنَّ ووردبريس يجب أن تكون قادرةً على الاتصال بقاعدة البيانات بنجاح.<br>
	ادخل إلى موقعك مجددًا لعل رسالة الخطأ تختفي، وإن بقيت موجودةً فلنحاول إصلاح قاعدة البيانات.
</p>

<h2 id="الخطوة-الثالثة-إصلاح-قاعدة-بيانات-ووردبريس">
	الخطوة الثالثة: إصلاح قاعدة بيانات ووردبريس
</h2>

<p>
	قد يحدث عطب في قاعدة بيانات ووردبريس في بعض الأحيان بسبب فشل الترقية أو انهيار قاعدة البيانات أو مشكلة في إحدى الإضافات، وقد تظهر هذه المشكلة على أنها خطأ في الاتصال بقاعدة البيانات، لذا إذا لم تكن المشكلة في خادوم MySQL ولا في ملف الضبط، فجرِّب إصلاح قاعدة البيانات.<br>
	توفر ووردبريس أداةً مبنيةً داخلها لإصلاح قاعدة البيانات، وهي معطلة افتراضيًا لعدم وجود قيود مفروضة على من يستطيع الوصول إليها مما قد يسبب مشكلةً أمنيةً، لذا سنفعِّل هذه الميزة، ثم نُشغِّل أداة الإصلاح، ثم نعطلها.<br>
	افتح ملف <code>wp-config.php</code> مرةً أخرى:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs lasso"><span class="pln">sudo nano </span><span class="pun">/</span><span class="hljs-built_in"><span class="kwd">var</span></span><span class="pun">/</span><span class="pln">www</span><span class="pun">/</span><span class="pln">html</span><span class="pun">/</span><span class="pln">wp</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">config</span></span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">php</span></code></pre>

<p>
	ألصق ما يلي في سطرٍ جديد:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs lasso"><span class="hljs-class"><span class="hljs-keyword"><span class="pln">define</span></span></span><span class="pun">(</span><span class="hljs-string"><span class="str">'WP_ALLOW_REPAIR'</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-literal"><span class="kwd">true</span></span><span class="pun">);</span></code></pre>

<p>
	سيؤدي السطر السابق إلى تفعيل ميزة إصلاح قاعدة البيانات.<br>
	احفظ الملف وأغلق المحرر النصي، وافتح العنوان الآتي في متصفحك، وتذكر أن تضع اسم النطاق الخاص بموقعك أو عنوان IP التابع له:
</p>

<pre class="ipsCode" id="ips_uid_2516_8">
<code class="hljs avrasm"><span class="hljs-label"><span class="pln">http</span><span class="pun">:</span></span><span class="com">//www</span><span class="hljs-preprocessor"><span class="com">.example</span></span><span class="hljs-preprocessor"><span class="com">.com</span></span><span class="com">/wp-admin/maint/repair</span><span class="hljs-preprocessor"><span class="com">.php</span></span></code></pre>

<p>
	يجب أن تظهر صفحة الإصلاح:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="25041" href="https://academy.hsoub.com/uploads/monthly_2017_09/1-wp-db-repair.png.b99f28fc341b68aead7503b72971b4ab.png" rel=""><img alt="1-wp-db-repair.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25041" data-unique="46yglhe2t" src="https://academy.hsoub.com/uploads/monthly_2017_09/1-wp-db-repair.thumb.png.317df2730b8988eac43910e696b14352.png"></a>
</p>

<p>
	اضغط على زر «Repair Database» ويجب أن تنتقل إلى صفحة النتائج التي تستطع أن ترى فيها التحققات والإصلاحات التي تجريها ووردبريس في الوقت الحقيقي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="25042" href="https://academy.hsoub.com/uploads/monthly_2017_09/2-wp-db-repair-results.png.23413ee7ea31dc27922f32bbbd0cbbd8.png" rel=""><img alt="2-wp-db-repair-results.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25042" data-unique="ovft6rk3v" src="https://academy.hsoub.com/uploads/monthly_2017_09/2-wp-db-repair-results.thumb.png.27afeac873a59f3c5d77b747221609c5.png"></a>
</p>

<p>
	بعد انتهاء هذه العملية، احرص على تعديل ملف <code>wp-config.php</code> وحذف السطر الذي أضفناه إليه آنفًا.<br>
	هل لاحظت أيّة إصلاحات أجرتها الأداة؟ جرِّب الدخول إلى موقعك مجددًا وانظر هل اختفت رسالة الخطأ. إذا ظهرت مشاكل لا يمكن حلها فربما ستحتاج إلى استعادة قاعدة البيانات من نسخة احتياطية إذا توافرت عندك. <br>
	إذا لم يُعثَر على مشاكل في قاعدة البيانات ولم تستطع أن تعرف ما أصل المشكلة، فمن المحتمل أن هنالك مشاكل أخرى لم تنتبه إليها.
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	أغلبية أخطاء “خطأ في إنشاء اتصال بقاعدة البيانات” يمكن حلّها عبر اتباع الخطوات السابقة، لكن مع ذلك هنالك أخطاء أكثر تعقيدًا قد تظهر على شكل خطأ في الاتصال بقاعدة البيانات؛ لذا سأعرض لك قائمةً بالمقالات التي تساعدك في تَتَبُع وإصلاح مسبب المشكلة:
</p>

<ul>
<li>
		أحد المسببات الشائعة للتراسل الكبير لموقع ووردبريس (وبالتالي انخفاض الأداء وحدوث أخطاء) هو هجمات brute-force ، وبالتالي يجب اتخاذ إجراءات للتخفيف من تأثيرها.
	</li>
	<li>
		يمكنك توفير بعض موارد الخادوم باستعمال التخزين المؤقت لصفحات ووردبريس؛ وهنالك عدد كبير من إضافات التخزين المؤقت البسيطة المتوافرة لها.
	</li>
</ul>
<p>
	<br>
	ترجمة –وبتصرّف– للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-debug-the-wordpress-error-establishing-database-connection" rel="external nofollow">How To Debug the Wordpress “Error Establishing Database Connection”‎</a> لصاحبه Brian Boucheron.
</p>

<p>
	حقوق الصورة البارزة محفوظة لـ <a href="http://www.freepik.com/free-vector/businessman-with-doubts_1104405.htm" rel="external nofollow">Freepik</a>
</p>
]]></description><guid isPermaLink="false">348</guid><pubDate>Fri, 15 Sep 2017 18:53:01 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x636;&#x628;&#x637; &#x645;&#x632;&#x627;&#x645;&#x646;&#x629; &#x627;&#x644;&#x648;&#x642;&#x62A; &#x641;&#x64A; &#x62E;&#x627;&#x62F;&#x648;&#x645; &#x623;&#x648;&#x628;&#x646;&#x62A;&#x648; 16.04</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%B6%D8%A8%D8%B7-%D9%85%D8%B2%D8%A7%D9%85%D9%86%D8%A9-%D8%A7%D9%84%D9%88%D9%82%D8%AA-%D9%81%D9%8A-%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1604-r347/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_09/59bad130976b5_main(37).png.eada42406f5456ed1eddf7676cc1b6fc.png" /></p>

<p>
	من المهم جدًا الحفاظ على دقة وقت النظام، سواءً فعلنا ذلك للحرص على دقة ترتيب السجلات (logs) أو أنَّ تحديثات قاعدة البيانات ستُطبَّق دون مشاكل؛ فإذا كان الوقت المضبوط على النظام غير صحيح، فقد يسبب ذلك أخطاءً أو تلفًا في البيانات أو مشاكل أخرى يصعب معرفة سببها بسهولة.<br>
	ميزة مزامنة الوقت مضمّنةٌ ومفعّلةٌ في أوبنتو 16.04 افتراضيًا عبر خدمة timesyncd، وسنلقي في هذا الدرس نظرةً على الأوامر الأساسية المتعلقة بالوقت، ونتأكد أنَّ خدمة timesyncd مفعّلة، ونتعلم كيفية تثبيت خدمة بديلة لمزامنة الوقت والتاريخ.
</p>

<h2 id="المتطلبات-المسبقة">
	المتطلبات المسبقة
</h2>

<p>
	يجب أن تملك قبل اتباع تعليمات هذا الدرس خادومًا يعمل بنظام أوبنتو 16.04 مع مستخدم ليس جذرًا لكنه يملك امتيازات الجذر عبر الأمر <code>sudo</code>؛ انظر إلى درس <a href="https://academy.hsoub.com/devops/servers/%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A7%D9%84%D8%A7%D8%A8%D8%AA%D8%AF%D8%A7%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r4/" rel="">الإعداد الابتدائي لخادوم أوبنتو 14.04</a>» لمزيدٍ من المعلومات.
</p>

<h2 id="تعلم-الأوامر-الأساسية-للتعامل-مع-الوقت">
	تعلّم الأوامر الأساسية للتعامل مع الوقت
</h2>

<p>
	إنَّ أبسط الأوامر لمعرفة ما هو الوقت الحالي في نظامك هو <code>date</code>، يمكن لأي مستخدم كتابة هذا الأمر للحصول على الوقت والتاريخ الحاليين:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
date</pre>

<p>
	مثال على الناتج:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs css"><span class="hljs-tag"><span class="typ">Wed</span></span><span class="pln"> </span><span class="hljs-tag"><span class="typ">Apr</span></span><span class="pln"> </span><span class="lit">26</span><span class="pln"> </span><span class="lit">17</span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">44</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">38</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">UTC</span></span><span class="pln"> </span><span class="lit">2017</span></code></pre>

<p>
	من المرجح أنَّ المنطقة الزمنية المستعملة في خادومك هي UTC كما هو ظاهر في المثال أعلاه، كلمة UTC هي اختصار لعبارة Coordinated Universal Time (التوقيت العالمي الموحد) وهو الوقت عند مبدأ خطوط الطول، واستعمال توقيت UTC سيسهل عليك العمل إذا كانت خواديمك تمتد لأكثر من منطقة زمنية وحيدة.<br>
	إذا أردت تغيير المنطقة الزمنية لأي سببٍ من الأسباب، فيمكنك استخدام الأمر <code>timedatectl</code> لفعل ذلك.<br>
	اعرض أولًا قائمةً بالمناطق الزمنية المتاحة:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs lasso"><span class="pln">timedatectl </span><span class="hljs-built_in"><span class="pln">list</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">timezones</span></span></code></pre>

<p>
	ستُعرَض قائمة بجميع المناطق الزمنية، يمكنك الضغط على زر Space للتمرير إلى الأسفل وزر b للتمرير إلى الأعلى؛ وبعد أن تعثر على المنطقة الزمنية الصحيحة فدوِّنها عندك ثم اضغط على q للخروج من القائمة.<br>
	يمكنك الآن ضبط القائمة الزمنية باستخدام الأمر <code>timedatectl set-timezone</code>، احرص على وضع منطقتك الزمنية بدلًا من تلك المذكورة في الأمر الآتي؛ لاحظ أنَّك ستحتاج إلى استخدام الأمر <code>sudo</code> مع الأمر <code>timedatectl</code> لإجراء هذا التعديل:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> timedatectl </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">-</span><span class="pln">timezone </span><span class="typ">America</span><span class="pun">/</span><span class="typ">New_York</span></code></pre>

<p>
	يمكنك التحقق من التغييرات بتشغيل الأمر <code>date</code> مجددًا:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs livecodeserver"><span class="hljs-built_in"><span class="pln">date</span></span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs css"><span class="hljs-tag"><span class="typ">Wed</span></span><span class="pln"> </span><span class="hljs-tag"><span class="typ">Apr</span></span><span class="pln"> </span><span class="lit">26</span><span class="pln"> </span><span class="lit">13</span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">55</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="lit">45</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">EDT</span></span><span class="pln"> </span><span class="lit">2017</span></code></pre>

<p>
	يجب أن يشير الاختصار المذكور في الأمر السابق إلى المنطقة الزمنية التي اخترتها.<br>
	تعلمنا كيف نتحقق من الوقت الحالي وكيف نضبط المناطق الزمنية، وسنتعلم الآن كيف نتأكد من مزامنة الوقت في نظامنا.
</p>

<h2 id="التحكم-بخدمة-timesyncd-بواسطة-timedatectl">
	التحكم بخدمة timesyncd بواسطة timedatectl
</h2>

<p>
	كانت أغلبية عمليات مزامنة الوقت تتم عبر خدمة بروتوكول وقت الشبكة (Network Time Protocol daemon) <code>ntpd</code>، أي سيتصل الخادوم إلى مجموعة من خواديم NTP التي توفر الوقت بدقة كبيرة.<br>
	لكن توزيعة أوبنتو تستعمل <code>timesyncd</code> بدلًا من <code>ntpd</code> لمزامنة الوقت، إذ تتصل خدمة <code>timesyncd</code> إلى خواديم الوقت نفسها وتعمل العمل نفسه تقريبًا، لكنها أخف وتندمج اندماجًا أفضل مع systemd وطريقة العمل الداخلية في توزيعة أوبنتو.<br>
	يمكنك الحصول على حالة خدمة <code>timesyncd</code> بتشغيل الأمر <code>timedatectl</code> دون معاملات، ولن تحتاج إلى استخدام <code>sudo</code> في هذا الموضع:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs "><span class="pln">timedatectl</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs livecodeserver"><span class="typ">Local</span><span class="pln"> </span><span class="hljs-built_in"><span class="pln">time</span></span><span class="pun">:</span><span class="pln"> </span><span class="typ">Wed</span><span class="pln"> </span><span class="hljs-number"><span class="lit">2017</span></span><span class="pun">-</span><span class="hljs-number"><span class="lit">04</span></span><span class="pun">-</span><span class="hljs-number"><span class="lit">26</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">17</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">07</span></span><span class="pln"> UTC
  </span><span class="typ">Universal</span><span class="pln"> </span><span class="hljs-built_in"><span class="pln">time</span></span><span class="pun">:</span><span class="pln"> </span><span class="typ">Wed</span><span class="pln"> </span><span class="hljs-number"><span class="lit">2017</span></span><span class="pun">-</span><span class="hljs-number"><span class="lit">04</span></span><span class="pun">-</span><span class="hljs-number"><span class="lit">26</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">17</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">07</span></span><span class="pln"> UTC
        RTC </span><span class="hljs-built_in"><span class="pln">time</span></span><span class="pun">:</span><span class="pln"> </span><span class="typ">Wed</span><span class="pln"> </span><span class="hljs-number"><span class="lit">2017</span></span><span class="pun">-</span><span class="hljs-number"><span class="lit">04</span></span><span class="pun">-</span><span class="hljs-number"><span class="lit">26</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">17</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">07</span></span><span class="pln">
       </span><span class="typ">Time</span><span class="pln"> zone</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Etc</span><span class="pun">/</span><span class="pln">UTC </span><span class="pun">(</span><span class="pln">UTC</span><span class="pun">,</span><span class="pln"> </span><span class="pun">+</span><span class="hljs-number"><span class="lit">0000</span></span><span class="pun">)</span><span class="pln">
 </span><span class="typ">Network</span><span class="pln"> </span><span class="hljs-built_in"><span class="pln">time</span></span><span class="pln"> </span><span class="hljs-command"><span class="hljs-keyword"><span class="pln">on</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-title"><span class="pln">yes</span></span></span><span class="pln">
NTP </span><span class="kwd">synchronized</span><span class="pun">:</span><span class="pln"> yes
 RTC </span><span class="hljs-operator"><span class="kwd">in</span></span><span class="pln"> </span><span class="hljs-built_in"><span class="kwd">local</span></span><span class="pln"> TZ</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">no</span></code></pre>

<p>
	سيطبع الأمر السابق الوقت المحلي والوقت العالمي (والذي يساوي الوقت المحلي في حال لم تغيّر المنطقة الزمنية)، وبعض معلومات عن حالة وقت الشبكة. السطر <code>Network time on: yes</code> يعني أنَّ خدمة timesyncd مفعّلة، والسطر <code>NTP synchronized: yes</code> يشير إلى نجاح مزامنة الوقت.<br>
	إذا لم تكن خدمة timesyncd مفعلةً، فشغِّلها باستعمال الأمر <code>timedatectl</code>:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs livecodeserver"><span class="pln">sudo timedatectl </span><span class="hljs-built_in"><span class="kwd">set</span></span><span class="pun">-</span><span class="pln">ntp </span><span class="hljs-command"><span class="hljs-keyword"><span class="pln">on</span></span></span></code></pre>

<p>
	شغِّل الأمر <code>timedatectl</code> مجددًا للتأكد من حالة وقت الشبكة؛ لاحظ أنَّ عملية التزامن تحتاج إلى بعض الوقت، لكن في النهاية يجب أن تكون قيمة السطرين <code>Network time on:‎</code> و <code>NTP synchronized:‎</code> تساوي <code>yes</code>.
</p>

<h3 id="التحويل-إلى-خدمة-ntpd">
	التحويل إلى خدمة ntpd
</h3>

<p>
	على الرغم من أنَّ خدمة timesyncd مناسبة لغالبية الاحتياجات، لكن بعض التطبيقات حساسةٌ جدًا لأدنى اضطراب في الوقت ومن المستحسن استعمال ntpd في هذه الحالات، لأنه يستعمل تقنيات معقدة لإبقاء الوقت في النظام مزامنًا دومًا.<br>
	علينا إيقاف خدمة timesyncd قبل تثبيت ntpd:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> timedatectl </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">-</span><span class="pln">ntp </span><span class="kwd">no</span></code></pre>

<p>
	للتأكد من إيقاف خدمة timesyncd:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs "><span class="pln">timedatectl</span></code></pre>

<p>
	ابحث عن السطر <code>Network time on: no</code> الذي يعني أنَّ خدمة <code>timdsyncd</code> متوقفة؛ يمكننا الآن تثبيت حزمة <code>ntp</code> باستعمال الأداة <code>apt-get</code>:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> apt</span><span class="pun">-</span><span class="kwd">get</span><span class="pln"> install ntp</span></code></pre>

<p>
	يجب أن يعمل خادوم ntpd تلقائيًا بعد التثبيت، يمكنك عرض حالة خدمة ntpd للتأكد أنَّ كل شيءٍ على ما يرام:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> ntpq </span><span class="pun">-</span><span class="pln">p</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_1834_7">
<code class="hljs avrasm"><span class="pln">remote           refid      </span><span class="hljs-keyword"><span class="pln">st</span></span><span class="pln"> t </span><span class="kwd">when</span><span class="pln"> poll reach   delay   offset  jitter
</span><span class="pun">==============================================================================</span><span class="pln">
</span><span class="hljs-number"><span class="lit">0.</span></span><span class="lit">ubuntu</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">pool</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">POOL</span></span><span class="pun">.</span><span class="pln">          </span><span class="hljs-number"><span class="lit">16</span></span><span class="pln"> p    </span><span class="pun">-</span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">1.</span></span><span class="lit">ubuntu</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">pool</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">POOL</span></span><span class="pun">.</span><span class="pln">          </span><span class="hljs-number"><span class="lit">16</span></span><span class="pln"> p    </span><span class="pun">-</span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">2.</span></span><span class="lit">ubuntu</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">pool</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">POOL</span></span><span class="pun">.</span><span class="pln">          </span><span class="hljs-number"><span class="lit">16</span></span><span class="pln"> p    </span><span class="pun">-</span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">
</span><span class="hljs-number"><span class="lit">3.</span></span><span class="lit">ubuntu</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">pool</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">POOL</span></span><span class="pun">.</span><span class="pln">          </span><span class="hljs-number"><span class="lit">16</span></span><span class="pln"> p    </span><span class="pun">-</span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">
ntp</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">ubuntu</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">com</span></span><span class="pln">  </span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">POOL</span></span><span class="pun">.</span><span class="pln">          </span><span class="hljs-number"><span class="lit">16</span></span><span class="pln"> p    </span><span class="pun">-</span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">0.000</span></span><span class="pln">
</span><span class="pun">-</span><span class="pln">makaki</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">miuku</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">ne</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">210.23</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">25</span></span><span class="hljs-number"><span class="lit">.77</span></span><span class="pln">     </span><span class="hljs-number"><span class="lit">2</span></span><span class="pln"> u   </span><span class="hljs-number"><span class="lit">45</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln">  </span><span class="hljs-number"><span class="lit">248.007</span></span><span class="pln">   </span><span class="pun">-</span><span class="hljs-number"><span class="lit">0.489</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">1.137</span></span><span class="pln">
</span><span class="pun">-</span><span class="hljs-number"><span class="lit">69.10</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">161</span></span><span class="hljs-number"><span class="lit">.7</span></span><span class="pln">     </span><span class="hljs-number"><span class="lit">144.111</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">222</span></span><span class="hljs-number"><span class="lit">.81</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> u   </span><span class="hljs-number"><span class="lit">43</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">90.551</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">4.316</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">0.550</span></span><span class="pln">
</span><span class="pun">+</span><span class="kwd">static</span><span class="pun">-</span><span class="pln">ip</span><span class="pun">-</span><span class="hljs-number"><span class="lit">85</span></span><span class="pun">-</span><span class="hljs-number"><span class="lit">25</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">130.149</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">17</span></span><span class="hljs-number"><span class="lit">.21</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">2</span></span><span class="pln"> u   </span><span class="hljs-number"><span class="lit">42</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">80.044</span></span><span class="pln">   </span><span class="pun">-</span><span class="hljs-number"><span class="lit">2.829</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">0.900</span></span><span class="pln">
</span><span class="pun">+</span><span class="pln">zepto</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">mcl</span></span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">gg</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">192.53</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">103</span></span><span class="hljs-number"><span class="lit">.108</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">2</span></span><span class="pln"> u   </span><span class="hljs-number"><span class="lit">40</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">64</span></span><span class="pln">    </span><span class="hljs-number"><span class="lit">3</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">83.331</span></span><span class="pln">   </span><span class="pun">-</span><span class="hljs-number"><span class="lit">0.385</span></span><span class="pln">   </span><span class="hljs-number"><span class="lit">0.391</span></span></code></pre>

<p>
	<code>ntpq</code> هي أداة لطلب (query) معلومات حول خدمة ntpd، والخيار <code>‎-p</code> يطلب معلومات حول خواديم NTP ‏(peers) التي اتصلت خدمة ntpd بها. قد يختلف الناتج عندك قليلًا، لكن يجب أن تتضمن القائمة على خواديم أوبنتو الافتراضية إضافةً إلى غيرها. أبقِ في ذهنك أنَّ خدمة ntpd تحتاج إلى بضع دقائق لتهيئة الاتصالات…
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	رأينا في هذا الدرس طريقة عرض وقت النظام، وكيفية تغيير المناطق الزمنية، وطريقة التعامل مع خدمة timesyncd الموجودة افتراضيًا في أوبنتو، إضافةً إلى طريقة تثبيت ntpd.<br>
	إذا كان نظامك ذو احتياجات خاصة لم نشرحها في هذا الدرس، فأنصحك بالرجوع إلى <a href="https://www.eecis.udel.edu/~mills/ntp/html/index.html" rel="external nofollow">توثيق NTP الرسمي</a>، وألقِ نظرةً على مشروع <a href="http://www.pool.ntp.org/" rel="external nofollow">NTP Pool</a> الذي هو مجموعةٌ من المتطوعين الذين يوفرون جزءًا كبيرًا من البنية التحتية التي يحتاج لها بروتوكول NTP في العالم.<br>
	ترجمة –وبتصرّف– للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-time-synchronization-on-ubuntu-16-04" rel="external nofollow">How To Set Up Time Synchronization on Ubuntu 16.04</a>لصاحبه Brian Boucheron
</p>

<p>
	حقوق الصورة البارزة محفوظة لـ <a href="http://www.freepik.com/free-photo/silver-alarm-clock-close_975599.htm" rel="external nofollow">Freepik</a>
</p>
]]></description><guid isPermaLink="false">347</guid><pubDate>Thu, 14 Sep 2017 18:58:21 +0000</pubDate></item><item><title>&#x62E;&#x637;&#x648;&#x627;&#x62A; &#x625;&#x636;&#x627;&#x641;&#x64A;&#x629; &#x644;&#x625;&#x639;&#x62F;&#x627;&#x62F; &#x62E;&#x648;&#x627;&#x62F;&#x64A;&#x645; CentOS 7 &#x627;&#x644;&#x62C;&#x62F;&#x64A;&#x62F;&#x629;</title><link>https://academy.hsoub.com/devops/linux/%D8%AE%D8%B7%D9%88%D8%A7%D8%AA-%D8%A5%D8%B6%D8%A7%D9%81%D9%8A%D8%A9-%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%AE%D9%88%D8%A7%D8%AF%D9%8A%D9%85-centos-7-%D8%A7%D9%84%D8%AC%D8%AF%D9%8A%D8%AF%D8%A9-r346/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_09/59b6cdfbaeb5f_main(33).png.2e04c2bf4a0d22aaf506566c7a15aef0.png" /></p>

<p>
	بعد إعداد أقل قدر ممكن من الضبط للخادوم الجديد <a href="https://academy.hsoub.com/devops/linux/%D8%A7%D9%84%D8%B6%D8%A8%D8%B7-%D8%A7%D9%84%D9%85%D8%A8%D8%AF%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-centos-7-r345/" rel="">الضبط المبدئي لخادوم CentOS 7</a>، هنالك بعض الخطوات الإضافية التي يُنصَح إجراؤها في أغلبية الحالات، وسنكمل ذلك في هذا الدرس بضبط بعض الأمور الاختيارية.
</p>

<h2 id="المتطلبات-المسبقة-وأهداف-هذا-الدرس">
	المتطلبات المسبقة وأهداف هذا الدرس
</h2>

<p>
	قبل أن تبدأ بهذا الدرس، عليك أن تتبع الخطوات المذكورة في درسنا السابق <a href="https://academy.hsoub.com/devops/linux/%D8%A7%D9%84%D8%B6%D8%A8%D8%B7-%D8%A7%D9%84%D9%85%D8%A8%D8%AF%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-centos-7-r345/" rel="">الضبط المبدئي لخادوم CentOS 7</a>، من المهم أن تعد حسابات المستخدمين، وتمنحهم امتيازات الجذر باستخدام الأمر <code>sudo</code>، وتحاول تأمين خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>.<br>
	يمكنك المتابعة مع هذا الدرس بعد إكمال الدرس السابق، الذي سنُركِّز فيه على ضبط بعض المكونات الاختيارية والمهمة؛ مثل ضبط الجدار الناري وملف التبديل (swap file) وضبط مزامنة الوقت والتاريخ عبر بروتوكول NTP.
</p>

<h2 id="ضبط-جدار-ناري-بسيط">
	ضبط جدار ناري بسيط
</h2>

<p>
	توفر الجدران النارية حمايةً أساسيةً للخواديم، وهذه التطبيقات مسؤولة عن منع الوصول إلى جميع المنافذ الشبكية على خادومك باستثناء المنافذ (أو الخدمات) التي سمحتَ لها.<br>
	تأتي توزيعة CentOS مع جدارٍ ناريٍ باسم <code>firewalld</code>، وتستعمل أداةٌ باسم <code>firewall-cmd</code> لضبط سياسات الجدار الناري. سنتبع منهجية لسياسات الجدار الناري ألا وهي إغلاق جميع المنافذ إلا التي نملك سببًا وجيهًا لإبقائها مفتوحةً.<br>
	لخدمة <code>firewalld</code> القدرة على إجراء تعديلات دون قطع الاتصالات الحالية، لذا يمكننا تشغيلها قبل أن نضيف الاستثناءات التي نريدها:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
sudo systemctl start firewalld</pre>

<p>
	لاحظ أنَّ الخدمة أصبحت تعمل الآن في الخلفية، ويمكننا استعمال الأداة <code>firewall-cmd</code> للحصول على معلوماتٍ عن سياسات الجدار الناري أو ضبطها.<br>
	لدى برمجية <code>firewalld</code> مفهوم هو «المناطق» (zones) لتسمية مدى ثقتك بالأجهزة الأخرى الموجودة على شبكة ما، وهذه التسمية ستمنحنا القدرة على إسناد قواعد مختلفة بناءً على مدى «ثقتنا» بالشبكة.<br>
	سنُعدِّل في درسنا هذا السياسات التابعة للمنطقة الافتراضية، وعندما نُعيد تحميل خدمة الجدار الناري، فستُطبَّق سياسات هذه المنطقة على جميع البطاقات الشبكية.<br>
	يمكننا البدء بإضافة استثناءات للخدمات المسموح لها بإجراء اتصالات خارجية؛ وأهمها خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، لأننا نريد أن نبقى قادرين على الاتصال البعيد إلى الخادوم.<br>
	إذا لم تُعدِّل المنفذ الذي تستمع عليه خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، فيمكنك السماح لاتصالات <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> بكتابة الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs brainfuck"><span class="hljs-comment"><span class="pln">sudo</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pln">firewall</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">cmd</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">permanent</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">add</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">service</span><span class="pun">=</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span></span></code></pre>

<p>
	أما إذا غيّرتَ منفذ <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> على خادومك، فعليك التصريح عن المنفذ الجديد يدويًا، وعليك أن تُحدِّد ما هو البروتوكول الذي تستعمله تلك الخدمة. نفِّذ الأمر الآتي إذا غيرتَ المنفذ الذي تستمع عليه خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs brainfuck"><span class="hljs-comment"><span class="pln">sudo</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pln">firewall</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">cmd</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">permanent</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">remove</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">service</span><span class="pun">=</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span></span><span class="pln">
</span><span class="hljs-comment"><span class="pln">sudo</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pln">firewall</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">cmd</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">permanent</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">add</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">port</span><span class="pun">=</span><span class="lit">4444</span><span class="pun">/</span><span class="pln">tcp</span></span></code></pre>

<p>
	هذا هو الحد الأدنى من الضبط لإبقاء الوصول إلى الخادوم البعيد ممكنًا، وإذا كنتَ تخطط لتشغيل خدمات أخرى على النظام، فعليك فتح منافذ لها في الجدار الناري.<br>
	فلو كنتَ تشغِّل خادوم ويب تقليدي وأردت السماح للاتصالات المتعلقة به في الجدار الناري:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs brainfuck"><span class="hljs-comment"><span class="pln">sudo</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pln">firewall</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">cmd</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">permanent</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">add</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">service</span><span class="pun">=</span><span class="pln">http</span></span></code></pre>

<p>
	إذا كنتَ تخطط لتشغيل خادوم ويب مع تشفير الاتصال عبر <abbr title="Secure Socket Layer | طبقة المنافذ الآمنة">SSL</abbr>/<abbr title="Transport Layer Security | بروتوكول أمن طبقة النقل">TLS</abbr>، فعليك السماح لخدمة <code>https</code> أيضًا:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs brainfuck"><span class="hljs-comment"><span class="pln">sudo</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pln">firewall</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">cmd</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">permanent</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">add</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">service</span><span class="pun">=</span><span class="pln">https</span></span></code></pre>

<p>
	وإذا احتجتَ إلى خدمة SMTP للبريد الإلكتروني، فنفِّذ الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs brainfuck"><span class="hljs-comment"><span class="pln">sudo</span></span><span class="pln"> </span><span class="hljs-comment"><span class="pln">firewall</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">cmd</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">permanent</span></span><span class="pln"> </span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">add</span></span><span class="hljs-literal"><span class="pun">-</span></span><span class="hljs-comment"><span class="pln">service</span><span class="pun">=</span><span class="pln">smtp</span></span></code></pre>

<p>
	لرؤية الخدمات الأخرى التي يمكن السماح لها بتحديد اسمها، فنفِّذ:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs lasso"><span class="pln">sudo firewall</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">cmd</span></span><span class="pln"> </span><span class="hljs-subst"><span class="pun">--</span></span><span class="kwd">get</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">services</span></span></code></pre>

<p>
	بعد أن تنتهي من ضبط الجدار الناري، يمكنك عرض قائمة بجميع الاستثناء الموجودة في سياسة الجدار الناري عبر الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs lasso"><span class="pln">sudo firewall</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">cmd</span></span><span class="pln"> </span><span class="hljs-subst"><span class="pun">--</span></span><span class="pln">permanent </span><span class="hljs-subst"><span class="pun">--</span></span><span class="hljs-built_in"><span class="pln">list</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">all</span></span></code></pre>

<p>
	وعندما تكون جاهزًا لتطبيق هذه التعديلات، فأعد تحميل الجدار الناري:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> firewall</span><span class="pun">-</span><span class="pln">cmd </span><span class="pun">--</span><span class="pln">reload</span></code></pre>

<p>
	وبعد أن تجرب وتتأكد من عمل كل الخدمات، فيجدر بك تفعيل الجدار الناري عند الإقلاع:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> systemctl enable firewalld</span></code></pre>

<p>
	تذكر أنَّ عليك فتح منفذ في الجدار الناري عند تثبيت وضبط أيّة خدمات جديدة لاحقًا.
</p>

<h2 id="ضبط-المنطقة-الزمنية-ومزامنة-الوقت-والتاريخ">
	ضبط المنطقة الزمنية ومزامنة الوقت والتاريخ
</h2>

<p>
	الخطوة التالية هي تعديل المنطقة الزمنية وضبط مزامنة الوقت عبر بروتوكول NTP (اختصار للعبارة Network Time Protocol).<br>
	أوّل خطوة هي التأكد من صحة المنطقة الزمنية المضبوطة في خادومك، والخطوة الثانية هي ضبط النظام ليزامن ساعته مع شبكة من خواديم NTP للحصول على الوقت والتاريخ بدقة، وهذا سيساعد في منع بعض المشاكل التي تحدث بسبب عدم تزامن الساعة.
</p>

<h3 id="ضبط-المنطقة-الزمنية">
	ضبط المنطقة الزمنية
</h3>

<p>
	أوّل خطوة هي ضبط المنطقة الزمنية للخادوم، وهذه الخطوة سهلة جدًا ويمكن إجراؤها باستعمال الأمر <code>timedatectl</code>.<br>
	علينا أولًا أن نعرض قائمة بالمناطق الزمنية المتوافرة بتنفيذ الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs lasso"><span class="pln">sudo timedatectl </span><span class="hljs-built_in"><span class="pln">list</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">timezones</span></span></code></pre>

<p>
	سيُنتِج الأمر السابق قائمةً بالمناطق الزمنية المتوافرة لخادومك، وعندما تجد المنطقة الزمنية الصحيحة فيمكنك ضبطها بتنفيذ الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> timedatectl </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">-</span><span class="pln">timezone region</span><span class="pun">/</span><span class="pln">timezone</span></code></pre>

<p>
	فمثلًا لو كان خادومك موجودًا في الساحل الشرقي للولايات المتحدة الأميركية، فيمكنك تنفيذ:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> timedatectl </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">-</span><span class="pln">timezone </span><span class="typ">America</span><span class="pun">/</span><span class="typ">New_York</span></code></pre>

<p>
	يمكنك التأكد أنَّ نظامك قد حُدِّث ليستعمل المنطقة الزمنية التي ضبطتَها بالأمر:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> timedatectl</span></code></pre>

<h3 id="ضبط-مزامنة-الوقت-عبر-بروتوكول-ntp">
	ضبط مزامنة الوقت عبر بروتوكول NTP
</h3>

<p>
	علينا الآن ضبط المزامنة بعد أن ضبطنا المنطقة الزمنية، وهذا يسمح للحاسوب بمزامنة الوقت والتاريخ، مما يمنع حدوث بعض المشاكل التي يتسبب بها الاختلاف في الوقت بين الخواديم.<br>
	سنستخدم خدمة باسم <code>ntp</code> لمزامنة الوقت، والتي يمكن تثبيتها من مستودعات CentOS:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> yum install ntp</span></code></pre>

<p>
	ثم عليك بدء الخدمة لهذه الجلسة، ثم تفعيل تشغيل الخدمة عند الإقلاع:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> systemctl start ntpd
</span><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> systemctl enable ntpd</span></code></pre>

<p>
	سيُصحِّح خادومك ساعته تلقائيًا لتتوافق مع الخواديم العالمية.
</p>

<h2 id="إنشاء-ملف-تبديل">
	إنشاء ملف تبديل
</h2>

<p>
	إضافة مساحة للتبديل (swap) إلى خادوم لينكس ستُمكِّن النظام من نقل المعلومات التي لا يتم الوصول إليها كثيرًا من ذاكرة الوصول العشوائي (RAM) إلى مكانٍ ما على القرص الصلب؛ وصحيحٌ أنَّ الوصول إلى البيانات المخزنة على القرص أبطأ بكثير بقارنة بالوصول إليها من ذاكرة الوصول العشوائي مباشرةً، لكن قد تستفيد من ذاكرة التبديل في حال نفدت المساحة المتاحة في ذاكرة RAM مما يمنع انهيار الخدمات التي يشغلها خادومك، يجدر بالذكر أنَّ استعمال مساحة التبديل مفيدٌ جدًا خصوصًا إذا كان خادومك يستضيف قواعد بيانات.<br>
	لا توجد قواعد لتحديد المساحة التخزينية المثلى لذاكرة التبديل، لكنها عمومًا تساوي مقدار ذاكرة RAM في نظامك أو ضعفيها…<br>
	احجز المساحة التي ترغب في استخدامها لذاكرة التبديل باستخدام الأداة <code>fallocate</code>، فلو أردنا إنشاء ملف للتبديل بمساحة 4 غيغابايت في مجلد <code>‎/swapfile</code> سنُنفِّذ الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> fallocate </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">l</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="lit">G</span><span class="pln"> </span><span class="pun">/</span><span class="pln">swapfile</span></code></pre>

<p>
	علينا بعد إنشاء الملف أن نمنع المستخدمين أو العمليات في النظام من الوصول إلى تلك الذاكرة وقراءة محتوياتها:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> chmod </span><span class="hljs-number"><span class="lit">600</span></span><span class="pln"> </span><span class="pun">/</span><span class="pln">swapfile</span></code></pre>

<p>
	بعد ضبط الأذونات السليمة للملف، فيمكننا أن نطلب من النظام أن يُهّيئ الملف ليعمل كذاكرة تبديل بالأمر:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> mkswap </span><span class="pun">/</span><span class="pln">swapfile</span></code></pre>

<p>
	ثم سنطلب من النظام استخدام ملف التبديل الذي أنشأناه آنفًا:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> swapon </span><span class="pun">/</span><span class="pln">swapfile</span></code></pre>

<p>
	أصبح نظامنا يستعمل ملف التبديل لحين إعادة إقلاعه، لذا سنحتاج إلى تعديل نظام الملفات لكي يفعل النظام ذلك تلقائيًا عند الإقلاع، وذلك بإضافة سطر جديد إلى ملف <code>‎/etc/fstab</code>:
</p>

<pre class="ipsCode" id="ips_uid_6395_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> sh </span><span class="pun">-</span><span class="pln">c </span><span class="hljs-string"><span class="str">'echo "/swapfile none swap sw 0 0" &gt;&gt; /etc/fstab'</span></span></code></pre>

<p>
	يجب أن يستعمل نظامك هذا الملف كذاكرة تبديل عند كل إقلاع.
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	عند هذه المرحلة يجب أن تكون قد ضبطت خادومك ضبطًا أساسيًا، ومن المرجح أن تكون عندك فكرة لما ستفعله لاحقًا، أنصحك بالاطلاع على المقالات الموجودة في قسم DevOps في <a href="https://academy.hsoub.com/devops/servers" rel="">أكاديمية حسوب</a>.
</p>

<p>
	<br>
	ترجمة –وبتصرّف– للمقال <a href="https://www.digitalocean.com/community/tutorials/additional-recommended-steps-for-new-centos-7-servers" rel="external nofollow">Additional Recommended Steps for New CentOS 7 Servers</a>لصاحبه Justin Ellingwood
</p>
]]></description><guid isPermaLink="false">346</guid><pubDate>Mon, 11 Sep 2017 17:55:49 +0000</pubDate></item><item><title>&#x627;&#x644;&#x636;&#x628;&#x637; &#x627;&#x644;&#x645;&#x628;&#x62F;&#x626;&#x64A; &#x644;&#x62E;&#x627;&#x62F;&#x648;&#x645; CentOS 7</title><link>https://academy.hsoub.com/devops/linux/%D8%A7%D9%84%D8%B6%D8%A8%D8%B7-%D8%A7%D9%84%D9%85%D8%A8%D8%AF%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-centos-7-r345/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_09/59b3dc63f121c_main(27).png.dc9bee6f33670db3dcd061a1359dbcc3.png" /></p>

<h2 id="تمهيد">
	تمهيد
</h2>

<p>
	هنالك بعض خطوات الضبط التي عليك إجراؤها عندما تُنشِئ خادومك، إذ ستزيد من حمايته وسهولة استخدامه، وستوفر لك أساسًا تستطيع البناء عليه لإجراء عمليات أخرى.
</p>

<h2 id="الخطوة-الأولى-تسجيل-الدخول-بحساب-الجذر">
	الخطوة الأولى: تسجيل الدخول بحساب الجذر
</h2>

<p>
	لتسجيل الدخول إلى خادومك، فعليك معرفة عنوان IP العام الخاص به إضافةً إلى كلمة مرور المستخدم الجذر <code>root</code>؛ إذا لم تُسجِّل دخولك من قبل إلى خادومك.<br>
	إذا لم تكن متصلًا بخادومك، فاستعمل الأمر الآتي الذي يُسجِّل دخولك بحساب الجذر <code>root</code>، لاحظ أنَّ عليك وضع عنوان IP العام لخادومك بدلًا من عبارة <code>SERVER_IP_ADDRESS</code>:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> root@SERVER_IP_ADDRESS</pre>

<p>
	أكمل عملية تسجيل الدخول بقبولك للتحذير عن صحة وموثوقية الخادوم إن ظهر لك، ثم بتوفيرك لطريقة الاستيثاق المطلوبة لحساب الجذر (عبر كلمة مرور أو مفتاح خاص [private key]).<br>
	إذا كانت هذه هي أوّل مرة تسجِّل فيها دخولك إلى الخادوم، فسيُطلَب منك تغيير كلمة مرور الجذر أيضًا.
</p>

<h3 id="ما-هو-المستخدم-الجذر">
	ما هو المستخدم الجذر؟
</h3>

<p>
	المستخدم الجذر <code>root</code> هو الحساب الإداري في بيئة لينكس والذي يملك صلاحيات وامتيازات واسعة جدًا؛ وبسبب امتلاك هذا الحساب لهذه الامتيازات، فمن غير المستحسن استعماله في الأحوال العادية، لأن القدرات التي يملكها حساب الجذر قادرة على إلحاق الضرر بنظامك، لو خطأً.<br>
	الخطوة التالية هي إعداد حساب مستخدم له صلاحيات أقل من صلاحيات الجذر لاستعماله في إجراء المهام اليومية، ثم سنتعلم كيف نزيد من امتيازات هذا الحساب عندما نحتاج إليها.
</p>

<h2 id="الخطوة-الثانية-إنشاء-حساب-مستخدم-جديد">
	الخطوة الثانية: إنشاء حساب مستخدم جديد
</h2>

<p>
	بعد أن نسجِّل الدخول بحساب الجذر <code>root</code>، فأصبحنا جاهزين لإضافة حساب مستخدم جديد الذي سنستعمله من الآن وصاعدًا لتسجيل الدخول إلى النظام.<br>
	سنُنشِئ بواسطة الأمر الآتي مستخدمًا جديدًا باسم <code>demo</code>، لكن يمكنك استخدام أي اسم يحلو لك:
</p>

<pre class="ipsCode" id="ips_uid_4436_8">
adduser demo</pre>

<p>
	علينا بعد ذلك أن نسند كلمة مرور إلى المستخدم الجديد (تذكر أن تضع اسم المستخدم الذي اخترته بدلًا من <code>demo</code>):
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs "><span class="pln">passwd demo</span></code></pre>

<p>
	ادخل كلمة مرور قوية، ثم كرِّر كتابتها للتأكيد.
</p>

<h2 id="الخطوة-الثالثة-الحصول-على-امتيازات-الجذر">
	الخطوة الثالثة: الحصول على امتيازات الجذر
</h2>

<p>
	أصبح لدينا الآن حساب مستخدم جديد يملك امتيازاتٍ عاديةً، لكننا سنحتاج في بعض الأحيان إلى إجراء عمليات إدارية.<br>
	ولتنجب الحاجة إلى تسجيل الخروج من حساب المستخدم العادي ثم الدخول مجددًا بحساب الجذر، فسنحاول ضبط إمكانية الحصول على امتيازات الجذر من حساب المستخدم العادي، وهذا يسمح للمستخدم العادي بتشغيل الأوامر بصلاحيات إدارية بوضع الكلمة <code>sudo</code> قبل كل أمر ينفذه.<br>
	لإضافة هذه الامتيازات إلى مستخدمنا الجديد، فعلينا إضافة المستخدم الجديد إلى مجموعة <code>wheel</code>؛ فالسلوك المبدئي لنظام CentOS 7 يسمح للمستخدمين الذين ينتمون إلى المجموعة <code>wheel</code> بالحصول على امتيازات الجذر باستعمال الأمر <code>sudo</code>.<br>
	نفِّذ الأمر الآتي بعد تسجيل دخولك بحساب الجذر لإضافة المستخدم الجديد إلى مجموعة <code>wheel</code> (لا تنسَ أن تضع اسم المستخدم الذي أنشَأته بدلًا من <code>demo</code>):
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs bash"><span class="pln">gpasswd </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">a</span></span><span class="pln"> demo wheel</span></code></pre>

<p>
	يمكن للمستخدم الآن أن ينفِّذ الأوامر بامتيازات الجذر؛ ولمزيدٍ من المعلومات عن هذا الموضوع، أنصحك بقراءة درس <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D9%8F%D8%AD%D8%B1%D9%91%D9%90%D8%B1-%D9%85%D9%84%D9%81%D9%91-sudoers-%D8%B9%D9%84%D9%89-ubuntu-%D9%88centos-r45/" rel="">How To Edit the Sudoers File on Ubuntu and CentOS</a>.
</p>

<h2 id="الخطوة-الرابعة-ضبط-الاستيثاق-عبر-مفتاح-عمومي-خطوة-مستحسنة">
	الخطوة الرابعة: ضبط الاستيثاق عبر مفتاح عمومي (خطوة مستحسنة)
</h2>

<p>
	الخطوة التالية في طريق زيادة حماية خادومك هي ضبط الاستيثاق عبر مفتاح عمومي (public key authentication) للمستخدم الجديد الذي أنشَأته؛ مما يزيد من حماية خادومك بطلب مفتاح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> خاص لإتمام تسجيل الدخول.
</p>

<h3 id="توليد-زوج-من-المفاتيح">
	توليد زوج من المفاتيح
</h3>

<p>
	إذا لم يكن لديك زوجٌ من مفاتيح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، والتي تتألف من مفتاح عمومي ومفتاح خاص، فعليك توليدها؛ أما إذا كان زوج المفاتيح متوافرًا عندك فاذهب إلى خطوة «نسخ المفتاح العمومي» مباشرةً.<br>
	نفِّذ الأمر الآتي في طرفية الجهاز المحلي لتوليد زوج جديد من المفاتيح:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs lasso"><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">keygen</span></span></code></pre>

<p>
	ولنفترض جدلًا أنَّ اسم المستخدم المحلي هو <code>localuser</code>، فستشاهد ناتجًا شبيهًا بالناتج الآتي:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs vbnet"><span class="typ">Generating</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pun">/</span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> rsa </span><span class="hljs-keyword"><span class="pln">key</span></span><span class="pln"> pair</span><span class="pun">.</span><span class="pln">
</span><span class="typ">Enter</span><span class="pln"> file </span><span class="hljs-keyword"><span class="kwd">in</span></span><span class="pln"> which </span><span class="hljs-keyword"><span class="pln">to</span></span><span class="pln"> save the </span><span class="hljs-keyword"><span class="pln">key</span></span><span class="pln"> </span><span class="pun">(</span><span class="str">/Users/</span><span class="pln">localuser</span><span class="pun">/.</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span><span class="pun">/</span><span class="pln">id_rsa</span><span class="pun">):</span></code></pre>

<p>
	اضغط على زر Enter لقبول اسم الملف ومساره، أو أدخِل اسمًا جديدًا له.<br>
	سيُطلَب منك الآن إدخال عبارة مرور (passphrase) لتأمين المفتاح، يمكنك أن تدخِل ما تشاء في هذا الحقل أو أن تتركه فارغًا.<br>
	ملاحظة: إذا تركتَ حقل عبارة المرور فارغًا فستتمكن من استخدام المفتاح الخاص للاستيثاق دون الحاجة إلى إدخال عبارة المرور؛ أما إذا أدخلت عبارة المرور، فعليك توفير المفتاح الخاص إضافةً إلى عبارة المرور عند تسجيل الدخول. وصحيحٌ أنَّ إنشاء مفاتيح محمية بعبارة مرور أكثر أمانًا، لكن هنالك مواطن استخدام لكلا الطريقتين اللتين تصنفان أنهما أكثر أمانًا من الاستيثاق التقليدي عبر كلمات المرور (passwords).<br>
	سيولّد مفتاح خاص باسم <code>id_rsa</code> ومفتاح عام باسم <code>id_rsa.pub</code> في مجلد <code>‎.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></code> الموجود في مجلد المنزل التابع للمستخدم المحلي <code>localuser</code>؛ تذكر أنَّ المفتاح الخاص يجب ألّا يُشارك مع أي شخص لا يحق له الوصول إلى خواديمك.
</p>

<h3 id="نسخ-المفتاح-العمومي">
	نسخ المفتاح العمومي
</h3>

<p>
	بعد توليد زوج مفاتيح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، عليك نسخ المفتاح العمومي إلى خادومك الجديد، وسنشرح طريقتين سهلتين لفعل ذلك.
</p>

<h3 id="الطريقة-الأولى-استخدام-سكربت-ssh-copy-id">
	الطريقة الأولى: استخدام سكربت <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>-copy-id
</h3>

<p>
	إذا كان السكربت <code><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>-copy-id</code> مثبتًا على جهازك المحلي، فيمكنك استخدامه لتثبيت المفتاح العمومي لأي مستخدم تملك معلومات الوصول الخاصة به.<br>
	شغِّل سكربت <code><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>-copy-id</code> بتحديد اسم المستخدم وعنوان IP للخادوم الذي تريد تثبيت المفتاح عليه، كما في الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs applescript"><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span><span class="pun">-</span><span class="hljs-keyword"><span class="pln">copy</span></span><span class="pun">-</span><span class="hljs-property"><span class="pln">id</span></span><span class="pln"> demo@SERVER_IP_ADDRESS</span></code></pre>

<p>
	بعد كتابة كلمة المرور عند طلبها، فيجب أن يُضاف المفتاح العمومي الخاص بك إلى ملف <code>‎.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/authorized_keys</code> في الخادوم البعيد؛ ويمكن الآن استخدام المفتاح الخاص لتسجيل الدخول إليه.
</p>

<h3 id="الطريقة-الثانية-تثبيت-المفتاح-يدويا">
	الطريقة الثانية: تثبيت المفتاح يدويًا
</h3>

<p>
	بفرض أنَّك ولدت زوجًا من مفاتيح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> باستعمال الخطوة السابقة، يمكنك تنفيذ الأمر الآتي في طرفية جهازك المحلي لطباعة محتويات المفتاح العمومي (<code>id_rsa.pub</code>):
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs avrasm"><span class="pln">cat </span><span class="pun">~</span><span class="str">/</span><span class="hljs-preprocessor"><span class="str">.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span></span><span class="str">/</span><span class="pln">id_rsa</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">pub</span></span></code></pre>

<p>
	يجب أن تظهر أمامك محتويات المفتاح العمومي، والذي سيبدو كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs perl"><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span><span class="pun">-</span><span class="pln">rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBGTO0tsVejssuaYR5R3Y</span><span class="pun">/</span><span class="pln">i73SppJAhme1dH7W2c47d4gOqB4izP</span><span class="hljs-number"><span class="pln">0</span></span><span class="pun">+</span><span class="pln">fRLfvbz</span><span class="pun">/</span><span class="pln">tnXFz4iOP</span><span class="pun">/</span><span class="pln">H6eCV05hqUhF</span><span class="pun">+</span><span class="typ">KYRxt9Y8tVMrpDZR2l75o6</span><span class="pun">+</span><span class="pln">xSbUOMu6xN</span><span class="pun">+</span><span class="pln">uVF0T9XzKcxmzTmnV7Na5up3QM3DoSRYX</span><span class="pun">/</span><span class="pln">EP3utr2</span><span class="pun">+</span><span class="pln">zAqpJIfKPLdA74w7g56oYWI9blpnpzxkEd3edVJOivUkpZ4JoenWManvIaSdMTJXMy3MtlQhva</span><span class="pun">+</span><span class="pln">j9CgguyVbUkdzK9KKEuah</span><span class="pun">+</span><span class="pln">pFZvaugtebsU</span><span class="pun">+</span><span class="pln">bllPTB0nlXGIJk98Ie9ZtxuY3nCKneB</span><span class="pun">+</span><span class="typ">KjKiXrAvXUPCI9mWkYS</span><span class="pun">/</span><span class="hljs-number"><span class="lit">1</span></span><span class="lit">rggpFmu3HbXBnWSUdf</span><span class="pln"> localuser</span><span class="hljs-variable"><span class="pln">@machine</span></span><span class="pun">.</span><span class="hljs-keyword"><span class="kwd">local</span></span></code></pre>

<p>
	حدِّد المفتاح العمومي وانسخه إلى الحافظة.<br>
	يجب أن نضيف المفتاح العمومي إلى ملفٍ خاص في مجلد المنزل للمستخدم الذي أنشأناه على الخادوم البعيد، وذلك لتمكين الاستيثاق عبره في <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>.<br>
	نُفِّذ الأمر الآتي بعد تسجيلك بحساب الجذر <code>root</code> إلى الخادوم للتبديل إلى حساب المستخدم الجديد الذي أنشأتَه (تذكر أن تضع الاسم الذي اخترتَه بدلًا من <code>demo</code>):
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs "><span class="pln">su </span><span class="pun">-</span><span class="pln"> demo</span></code></pre>

<p>
	ستنتقل الآن إلى مجلد المنزل الخاص بالمستخدم الجديد.<br>
	أنشِئ مجلدًا جديدًا باسم <code>‎.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></code> وامنع بقية المستخدمين من الوصول إليه، وذلك بتنفيذ الأمرين الآتيين:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs perl"><span class="hljs-keyword"><span class="pln">mkdir</span></span><span class="pln"> </span><span class="pun">.</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>
</span><span class="hljs-keyword"><span class="pln">chmod</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">700</span></span><span class="pln"> </span><span class="pun">.</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span></code></pre>

<p>
	أنشِئ ملفًا جديدًا في مجلد <code>‎.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></code> باسم <code>authorized_keys</code> باستعمال محررك النصي المفضل، سنستخدم هنا محرر vi لتعديل الملف :
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs avrasm"><span class="pln">vi </span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span></span><span class="pun">/</span><span class="pln">authorized_keys</span></code></pre>

<p>
	بدِّل إلى نمط الإدخال بالضغط على <code>i</code> ثم ألصق المفتاح العمومي (الذي يجب أن يكون موجودًا في الحافظة)، ثم اضغط على زر <code>ESC</code> للخروج من نمط الإدخال.<br>
	أدخِل <code>‎:x</code> ثم اضغط على Enter لحفظ الملف والخروج من المحرر النصي.<br>
	ثم امنع الوصول إلى ملف <code>authorized_keys</code> لجميع المستخدمين ما عدا المستخدم المالك باستعمال هذا الأمر:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs perl"><span class="hljs-keyword"><span class="pln">chmod</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">600</span></span><span class="pln"> </span><span class="pun">.</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span><span class="pun">/</span><span class="pln">authorized_keys</span></code></pre>

<p>
	ثم نفِّذ هذا الأمر مرةً واحدةً للعودة إلى حساب المستخدم الجذر:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs bash"><span class="hljs-keyword"><span class="kwd">exit</span></span></code></pre>

<p>
	يمكنك الآن تسجيل الدخول بحساب المستخدم الجديد عبر <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> باستعمال المفتاح الخاص للاستيثاق.<br>
	لمزيدٍ من المعلومات حول طريقة عمل الاستيثاق عبر المفاتيح، فأنصحك بقراءة مقالة <a href="https://academy.hsoub.com/devops/security/ssh/%D8%A7%D9%84%D8%B9%D9%85%D9%84-%D9%85%D8%B9-%D8%AE%D9%88%D8%A7%D8%AF%D9%8A%D9%85-ssh-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D9%85%D9%81%D8%A7%D8%AA%D9%8A%D8%AD-r55/" rel="">العمل مع خواديم <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>: العملاء والمفاتيح</a>.
</p>

<h2 id="الخطوة-الخامسة-ضبط-خدمة-ssh">
	الخطوة الخامسة: ضبط خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>
</h2>

<p>
	بعد تهيئتنا لحساب المستخدم الجديد، فيمكننا الآن تأمين الخادوم قليلًا بتعديل ضبط خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> (وهي الخدمة التي تسمح لنا بتسجيل الدخول عن بعد) لمنع الوصول عبر <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> إلى حساب الجذر <code>root</code>.<br>
	ابدأ بفتح ملف الضبط بمحررك النصي المفضل باستعمال حساب الجذر <code>root</code>:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs "><span class="pln">vi </span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span><span class="pun">/</span><span class="pln">sshd_config</span></code></pre>

<p>
	يمكننا هنا تعطيل تسجيل الدخول بحساب الجذر إلى <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، وهذا أكثر أمانًا، وتذكر أننا نستطيع الوصول إلى خادومنا عبر حساب المستخدم العادي ثم الحصول على امتيازات الجذر عند اللزوم.<br>
	لتعطيل تسجيل الدخول لحساب الجذر عن بعد، عليك العثور على سطرٍ شبيهٍ بالسطر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs vala"><span class="hljs-preprocessor"><span class="com">#PermitRootLogin yes</span></span></code></pre>

<p>
	تلميح: للبحث عن السطر السابق في محرر vi، يمكنك أن تكتب <code>‎/PermitRoot</code> ثم تضغط على Enter، مما سيحرك المؤشر إلى الحرف P في السطر السابق.<br>
	احذف رمز التعليق من السطر السابق بحذف محرف <code>#</code> (اضغط على <code>Shift-x</code>).<br>
	ثم انقل المؤشر إلى الكلمة <code>yes</code> بالضغط على <code>c</code>.<br>
	استبدل كلمة <code>yes</code> بالضغط على <code>cw</code> ثم اكتب الكلمة <code>no</code> ثم اضغط على زر Escape بعد أن تنتهي من التعديلات؛ ويجب أن يصبح السطر كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs perl"><span class="typ">PermitRootLogin</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">no</span></span></code></pre>

<p>
	أدخِل <code>‎:x</code> ثم Enter لحفظ الملف والخروج من المحرر النصي.
</p>

<h3 id="إعادة-تحميل-خدمة-ssh">
	إعادة تحميل خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>
</h3>

<p>
	بعد أن أجرينا تعديلاتنا، سنحتاج إلى إعادة تشغيل خدمة <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> لكي تستعمل الضبط المُعدَّل.<br>
	اكتب السطر الآتي لإعادة تحميل <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs "><span class="pln">systemctl reload sshd</span></code></pre>

<p>
	قبل أن نُسجِّل خروجنا من الخادوم، علينا أن نختبر الضبط الجديد، فلا نريد أن نقطع الاتصال قبل أن نتأكد من إمكانية إنشاء اتصالات جديدة بنجاح.<br>
	افتح نافذة طرفية جديدة لإنشاء اتصال جديد إلى الخادوم، لكن هذه المرة سنستخدم حساب المستخدم الجديد للاتصال بدلًا من حساب الجذر.<br>
	سنستخدم الأمر الآتي للاتصال إلى الخادوم، تذكر أن تضع المعلومات الخاصة بمستخدمك بما يناسب الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs ruby"><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> demo</span><span class="hljs-variable"><span class="pln">@SERVER_IP_ADDRESS</span></span></code></pre>

<p>
	ملاحظة: إذا كنتَ تستخدم برمجية PuTTY للاتصال إلى خواديمك، فاحرص على تحديث رقم المنفذ ليُطابِق إعدادات النظام الحالي.<br>
	تذكر أنَّ تضع الأمر <code>sudo</code> قبل الأوامر التي تريد تنفيذها بامتيازات الجذر كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> command_to_run</span></code></pre>

<p>
	إذا جرى كل شيءٍ على ما يرام، فاخرج من كلا الجلستين بكتابة:
</p>

<pre class="ipsCode" id="ips_uid_4436_10">
<code class="hljs bash"><span class="hljs-keyword"><span class="kwd">exit</span></span></code></pre>

<h2 id="ما-هي-الخطوات-القادمة">
	ما هي الخطوات القادمة؟
</h2>

<p>
	أنشأنا في هذا الدرس أساسًا صلبًا لخادومك، ويمكنك الآن تثبيت أي برمجيات تحتاج لها عليه.<br>
	لمزيدٍ من المعلومات حول الخواديم عمومًا، فتصفح قسم DevOps في <a href="https://academy.hsoub.com/devops/" rel="">أكاديمية حسوب</a>
</p>

<p>
	<br>
	ترجمة –وبتصرف– للمقال <a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-centos-7" rel="external nofollow">Initial Server Setup with CentOS 7 </a>لصاحبه Mitchell Anicas
</p>
]]></description><guid isPermaLink="false">345</guid><pubDate>Sat, 09 Sep 2017 12:20:43 +0000</pubDate></item><item><title>&#x645;&#x642;&#x62F;&#x645;&#x629; &#x625;&#x644;&#x649; &#x646;&#x638;&#x627;&#x645; &#x645;&#x644;&#x641;&#x627;&#x62A; &#x644;&#x64A;&#x646;&#x643;&#x633; EXT4</title><link>https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D9%86%D8%B8%D8%A7%D9%85-%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D9%84%D9%8A%D9%86%D9%83%D8%B3-ext4-r343/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_11/3edit.png.6fe1629aee000a6b8571f5c508d2c393.png" /></p>

<p>
	سنتعلم في هذا الدرس، بعض المعلومات عن تاريخ نظام ملفات EXT4 وعن ميزاته واستخدامه الأمثل، وسنناقش الاختلافات بينه وبين الإصدارات السابقة من أنظمة ملفات EXT.<br>
	أريد في هذا الدرس تفصيل مواصفات أنظمة ملفات EXT، لكنني سأبدأ أولًا بالإجابة على التساؤل «ما هو نظام الملفات»، نظام الملفات يقوم بما يلي:
</p>

<ol>
<li>
		تخزين البيانات: إذ إنَّ الغرض الرئيسي لأي نظام ملفات هو توفير مكان منظم ومُهيكل لتخزين البيانات والحصول عليها.
	</li>
	<li>
		توفير مجالات أسماء (namespaces): إذ يوفر نظام الملفات منهجية تنظيمية لتسمية وهيكلة البيانات.
	</li>
	<li>
		توفير نموذج أمني (security model): الذي يُعرِّف امتيازات الوصول إلى البيانات المخزنة.
	</li>
	<li>
		توفير واجهة برمجية (<abbr title="Application Programming Interface | واجهة برمجية">API</abbr>): وهي الدوال (functions) التي تستخدم لتتعامل مع الكائنات الموجودة في نظام الملفات مثل المجلدات والملفات.
	</li>
	<li>
		توفير برمجيات لتطبيق المواصفات السابقة.
	</li>
</ol>
<p>
	سنركِّز في درسنا على أوّل عنصر من القائمة السابقة ونستكشف بنى البيانات الوصفية (metadata) التي توفر إطار العمل المنطقي (logical framework) لتخزين البيانات في أنظمة ملفات EXT.
</p>

<h2>
	<a id="___EXT_8" rel=""></a>تاريخ نظام ملفات EXT
</h2>

<p>
	صحيحٌ أنَّ نظام ملفات EXT قد كُتِبَ لأنظمة لينكس، لكن جذوره تتأصل في نظام تشغيل Minix ونظام ملفاته، والذي يسبق ظهور لينكس بخمس سنوات، إذ نُشِر أوّل مرة في عام 1987.<br>
	سيسهل علينا فهم نظام ملفات EXT4 إذا نظرنا نظرةً شموليةً على تاريخ نظام ملفات EXT والتطور التقني الذي حدث لعائلة أنظمة ملفات EXT بدءًا من أصولها في نظام Minix.
</p>

<h2>
	<a id="__Minix_11" rel=""></a>نظام ملفات Minix
</h2>

<p>
	عندما كان Linus Torvalds يكتب نواة لينكس، احتاج إلى نظام ملفات لكنه لم يرغب بكتابة واحد، لذا ضمّن <a href="https://en.wikipedia.org/wiki/MINIX_file_system" rel="external nofollow">نظام ملفات Minix</a> الذي كتبه <a href="https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum" rel="external nofollow">Andrew S. Tanenbaum</a> وكان جزءًا من <a href="https://en.wikipedia.org/wiki/MINIX" rel="external nofollow">نظام تشغيل Minix</a>؛ والذي هو نظام تشغيل شبيه بِيونكس (Unix-like) كُتِبَ لأغراضٍ تعليمية، وكانت شيفرته المصدرية متوافرة مجانًا ومرخصة برخصة سمحت بتضمينها في أوّل نسخة من نواة لينكس.<br>
	هذه هي بنية نظام ملفات Minix، والتي تتواجد أغلبية مكوناتها في القسم (partition) الذي يستعمل نظام الملفات السابق:
</p>

<ul>
<li>
		قطاع الإقلاع (boot sector) الموجود في أوّل قطاع (sector) في القرص الصلب الذي يحتوي على نظام الملفات؛ يحتوي قطاع الإقلاع على سجل إقلاع صغير جدًا إضافةً إلى جدول الأقسام (partition table).
	</li>
	<li>
		أوّل قطاع في كل قسم يسمى قطاع superblock، الذي يحتوي على البيانات الوصفية التي تُعرِّف البنى الأخرى الموجودة في نظام الملفات وتحدد مكانها في القرص الفيزيائي.
	</li>
	<li>
		قطاع بقائمة مؤشرات الفهرسة (inode)، التي تحدد ما هي مؤشرات الفهرسة المستخدمة والمتاحة للاستخدام.
	</li>
	<li>
		مؤشرات الفهرسة، التي لها مساحة خاصة على القرص، وكل مؤشر فهرسة يملك معلومات عن ملف واحد، بما في ذلك مكان كتل البيانات (data blocks)، أي ما هي المناطق على القرص التي ترتبط بهذا الملف.
	</li>
	<li>
		قائمة بالمناطق (zone bitmap)، والتي تَتَبَّع مناطق البيانات المستخدمة والحرة.
	</li>
	<li>
		منطقة تخزين البيانات (date zone)، وهي مكان تخزين البيانات.
	</li>
</ul>
<p>
	سُيستعمل –لكلا نوعَي القوائم السابقين– بت (bit) وحيد لتمثيل منطقة بيانات أو مؤشر فهرسة واحد؛ فإذا كانت قيمة البت تساوي الصفر فهذا يعني أنَّ منطقة التخزين أو مؤشر الفهرسة حر ويمكن استخدامه، أما إذا كانت قيمة البت تساوي الواحد فهذا يعني أنَّ منطقة البيانات أو مؤشر الفهرسة قيد الاستخدام.<br>
	حسنًا، ما هو «مؤشر الفهرسة» (<a href="https://en.wikipedia.org/wiki/Inode" rel="external nofollow">inode</a>)، إنه اختصارٌ للكلمة index-node، إذ إنَّ مؤشر الفهرسة هو كتلة موجودة على القرص مساحتها 256 بايت التي تخزِّن بيانات تصف الملف.<br>
	هذه البيانات تتضمن حجم الملف، ومُعرِّف المستخدم (user ID) للمستخدم المالك للملف وللمجموعة المالكة، إضافةً إلى نمط الملف (أي أذونات الوصول)؛ مع تخزين ثلاث بصمات وقت (timestamps) التي تُحدِّد ما هو الوقت والتاريخ الذي تم الوصول إلى الملف آخر مرة، ومتى عُدِّل، ومتى تغيّرت البيانات الموجودة في مؤشر الفهرسة آخر مرة.<br>
	يحتوي مؤشر الفهرسة على معلومات تُشير إلى مكان تخزين بيانات الملف على القرص الصلب، وهذه المعلومات هي قائمة بمناطق البيانات (أو كتل البيانات) في أنظمة ملفات Minix و EXT1-3.<br>
	كان مؤشر الفهرسة في نظام ملفات Minix يدعم تخزين تسع كتل بيانات، سبعٌ منها مباشر واثنان ليستا مباشرتين؛ إذا أردت تعلم المزيد عن بنية نظام ملفات Minix فأنصحك بإلقاء نظرة على <a href="http://ohm.hgesser.de/sp-ss2012/Intro-MinixFS.pdf" rel="external nofollow">مستند PDF الآتي الذي يشرح ذلك بالتفصيل</a> واقرأ لمحةً عامةً عن بنية مؤشرات الفهرسة في <a href="https://en.wikipedia.org/wiki/Inode_pointer_structure" rel="external nofollow">ويكيبيديا</a>.
</p>

<h2>
	<a id="EXT_25" rel=""></a>EXT
</h2>

<p>
	<a href="https://en.wikipedia.org/wiki/Extended_file_system" rel="external nofollow">نظام الملفات EXT</a> الأصلي (الذي يرمز اسمه إلى Extended) كتبه <a href="https://en.wikipedia.org/wiki/R%C3%A9my_Card" rel="external nofollow">Rémy Card</a> ونُشِرَ مع نواة لينكس في عام 1992 لتجاوز بعض محدوديات التخزين في نظام ملفات Minix، وكانت التغيرات البنيوية الرئيسية حدثت للبيانات الوصفية لنظام الملفات، والتي أصبحت مبنية على نظام ملفات Unix ‏(UFS)، والذي أصبح معروفًا بنظام ملفات FFS (اختصار للعبارة Berkeley Fast File System).<br>
	وجدتُ قدرًا ضئيلًا من المعلومات المنشورة عن نظام ملفات EXT التي يمكن التأكد منها، وأرجِّح ذلك بسبب المشاكل الكبيرة التي كان يواجهها هذا النظام، ولأن نظام ملفات EXT2 استبدله بعد فترةٍ قليلة.
</p>

<h2>
	<a id="EXT2_28" rel=""></a>EXT2
</h2>

<p>
	<a href="https://en.wikipedia.org/wiki/Ext2" rel="external nofollow">نظام ملفات EXT2</a> كان ناجحًا جدًا، إذ استعمل في توزيعات لينكس لسنواتٍ عدِّة، وكان أوّل نظام ملفات تعاملتُ معه عندما بدأت باستخدام Red Hat Linux 5.0 في عام 1997.<br>
	كان نظام ملفات EXT2 يملك بنية البيانات الوصفية الموجودة في نظام ملفات EXT نفسها، لكن نظام ملفات EXT2 كان متطلعًا للمستقبل، إذ ترك مساحةً كبيرةً بين بنى البيانات الوصفية لاستخدامها مستقبلًا.<br>
	وكما في نظام ملفات Minix، امتلك EXT2 قطاع إقلاع في أوّل قطاع موجود على القرص الصلب الذي ثُبِّتَ عليه، والتي يحتوي على سجل إقلاع صغير جدًا وجدول أقسام، وكانت هنالك مساحة محجوزة بعد قطاع الإقلاع، والتي تمتد من قطاع الإقلاع إلى أوّل قسم في القرص الصلب. يستعمل مُحمِّل الإقلاع <a href="https://opensource.com/article/17/2/linux-boot-and-startup" rel="external nofollow">GRUB2</a> (أو GRUB1) هذه المساحة لتخزين شيفرة الإقلاع الخاصة به.<br>
	المساحة الموجودة في كل قسم EXT2 تُقسَّم إلى مجموعات أسطوانية (cylinder groups) التي تسمح بإدارة جزيئية (granular management) للمساحة التخزينية. تُظهِر الصورة التالية البنية الأساسية للمجموعات الأسطوانية (والتي تكون مساحة كل واحدة منها –حسب خبرتي– حوالي 8 ميغابايت)، تذكر أنَّ واحدة تخزين البيانات في الأسطوانة هي الكتلة، والتي تساوي 4 كيلوبايت تقريبًا.
</p>

<p style="text-align: center;">
	<img alt="1-cylindergroup-01_1.png" class="ipsImage ipsImage_thumbnailed" data-fileid="24903" data-unique="jj9mq7mub" src="https://academy.hsoub.com/uploads/monthly_2017_09/1-cylindergroup-01_1.png.99ed4029f80e0b91749e83dfdbf1931d.png"></p>

<p>
	<br>
	أوّل قطاع في المجموعة الأسطوانية يسمى قطاع superblock، الذي يحتوي على البيانات الوصفية التي تُعرِّف البنى الأخرى التابعة لنظام الملفات وتحدد مكانها في القرص الفيزيائي.<br>
	يمكن استبدال قطاع superblock معطوب باستخدام أدوات التعامل مع الأقراص مثل dd، وذلك باستعادة محتويات نسخة احتياطية من قطاع superblock، ولا يحدث ذلك عادةً، لكن منذ عدِّة سنوات حدث ذلك معي، واستطعت استعادة محتويات قطاع superblock من إحدى النسخ الاحتياطية، ولحسن الحظ كنتُ محتاطًا لهذا الأمر واستعملتُ الأمر <code>dumpe2fs</code> للحصول على بيانات الأقسام الموجودة في نظامي.<br>
	ما يلي هو جزء من ناتج الأمر <code>dumpe2fs</code>، الذي يُظهِر البيانات الوصفية الموجودة في قطاع superblock، إضافةً إلى بيانات عن أوّل مجموعتين أسطوانيتين في نظام الملفات:
</p>

<pre class="ipsCode" id="ips_uid_2712_7">
# dumpe2fs /dev/sda1
Filesystem volume name:   boot 
Last mounted on:          /boot 
Filesystem UUID:          79fc5ed8-5bbc-4dfe-8359-b7b36be6eed3 
Filesystem magic number:  0xEF53 
Filesystem revision #:    1 (dynamic) 
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir nlink extra_isize 
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl 
Filesystem state:         clean 
Errors behavior:          Continue 
Filesystem OS type:       Linux 
Inode count:              122160 
Block count:              488192 
Reserved block count:     24409 
Free blocks:              376512 
Free inodes:              121690 
First block:              0 
Block size:               4096 
Fragment size:            4096 
Group descriptor size:    64 
Reserved GDT blocks:      238 
Blocks per group:         32768 
Fragments per group:      32768 
Inodes per group:         8144 
Inode blocks per group:   509 
Flex block group size:    16 
Filesystem created:       Tue Feb  7 09:33:34 2017 
Last mount time:          Sat Apr 29 21:42:01 2017 
Last write time:          Sat Apr 29 21:42:01 2017 
Mount count:              25 
Maximum mount count:      -1 
Last checked:             Tue Feb  7 09:33:34 2017 
Check interval:           0 (&lt;none&gt;) 
Lifetime writes:          594 MB 
Reserved blocks uid:      0 (user root) 
Reserved blocks gid:      0 (group root) 
First inode:              11 
Inode size:               256 
Required extra isize:     32 
Desired extra isize:      32 
Journal inode:            8 
Default directory hash:   half_md4 
Directory Hash Seed:      c780bac9-d4bf-4f35-b695-0fe35e8d2d60 
Journal backup:           inode blocks 
Journal features:         journal_64bit 
Journal size:             32M 
Journal length:           8192 
Journal sequence:         0x00000213 
Journal start:            0 
 
 
Group 0: (Blocks 0-32767) 
 Primary superblock at 0, Group descriptors at 1-1 
 Reserved GDT blocks at 2-239 
 Block bitmap at 240 (+240) 
 Inode bitmap at 255 (+255) 
 Inode table at 270-778 (+270) 
 24839 free blocks, 7676 free inodes, 16 directories 
 Free blocks: 7929-32767 
 Free inodes: 440, 470-8144 
Group 1: (Blocks 32768-65535) 
 Backup superblock at 32768, Group descriptors at 32769-32769 
 Reserved GDT blocks at 32770-33007 
 Block bitmap at 241 (bg #0 + 241) 
 Inode bitmap at 256 (bg #0 + 256)
 Inode table at 779-1287 (bg #0 + 779) 
 8668 free blocks, 8142 free inodes, 2 directories 
 Free blocks: 33008-33283, 33332-33791, 33974-33975, 34023-34092, 34094-34104, 34526-34687, 34706-34723, 34817-35374, 35421-35844, 35935-36355, 36357-36863, 38912-39935, 39940-40570, 42620-42623, 42655, 42674-42687, 42721-42751, 42798-42815, 42847, 42875-42879, 42918-42943, 42975, 43000-43007, 43519, 43559-44031, 44042-44543, 44545-45055, 45116-45567, 45601-45631, 45658-45663, 45689-45695, 45736-45759, 45802-45823, 45857-45887, 45919, 45950-45951, 45972-45983, 46014-46015, 46057-46079, 46112-46591, 46921-47103, 49152-49395, 50027-50355, 52237-52255, 52285-52287, 52323-52351, 52383, 52450-52479, 52518-52543, 52584-52607, 52652-52671, 52734-52735, 52743-53247 
 Free inodes: 8147-16288 
Group 2: (Blocks 65536-98303) 
 Block bitmap at 242 (bg #0 + 242) 
 Inode bitmap at 257 (bg #0 + 257) 
 Inode table at 1288-1796 (bg #0 + 1288) 
 6326 free blocks, 8144 free inodes, 0 directories 
 Free blocks: 67042-67583, 72201-72994, 80185-80349, 81191-81919, 90112-94207 
 Free inodes: 16289-24432 
Group 3: (Blocks 98304-131071)
 
&lt;snip&gt;</pre>

<p>
	كل مجموعة أسطوانية لها قائمة مؤشرات الفهرسة الخاصة بها التي تستخدم لتحديد ما هي مؤشرات الفهرسة المستعملة والحرة في تلك المجموعة. تملك مؤشرات الفهرسة مساحةً خاصةً لها في كل مجموعة، وكل مؤشر فهرسة يحتوي على معلومات عن ملفٍ وحيد، بما في ذلك مكان كتل البيانات التي تتعلق بذاك الملف.<br>
	أما قائمة الكتل فتَتَبّع كتل البيانات الحرة والمستخدمة ضمن نظام الملفات؛ لاحظ وجود قدر كبير من البيانات حول نظام الملفات في الناتج السابق، وستكون معلومات المجموعات طويلةً جدًا في أنظمة الملفات الكبيرة؛ إذ تتضمن البيانات الوصفية الخاصة بالمجموعة الأسطوانية قائمةً بجميع كتل البيانات الحرة فيها.<br>
	يُطبِّق نظام ملفات EXT استراتيجيات لتوزيع البيانات التي تحرص على تقليل تجزئة الملف قدر المستطاع، وتقليل التجزئة سيُحسِّن من أداء نظام الملفات، وهذه الاستراتيجيات مشروحة في قسم EXT4 أدناه.<br>
	أكبر مشكلة مع نظام ملفات EXT2 –التي واجهتني في بعض المناسبات– هي الزمن الطويل الذي يقدر بالساعات لاستعادة نظام الملفات بعد حدوث انهيار مفاجئ، لأنَّ برنامج fsck (اختصار للعبارة file system check) كان يأخذ وقتًا طويلًا للعثور على التضاربات في نظام الملفات وتصحيحها.<br>
	ففي إحدى المرات أخذت استعادة القرص في أحد حواسيبي بعد حدوث انهيار ما يزيد عن 28 ساعة، وكان حجم الأقراص آنذاك قليلًا ويقدر ببضع مئات من الميغابايتات.
</p>

<h2>
	<a id="EXT3_124" rel=""></a>EXT3
</h2>

<p>
	كان <a href="https://en.wikipedia.org/wiki/Ext3" rel="external nofollow">لنظام ملفات EXT3</a> هدفٌ وحيدٌ ألا وهو التغلب على مشكلة استغراق الأمر fsck وقتًا طويلًا لاستعادة بنية القرص المعطوبة بسبب حدوث إغلاق غير سليم الذي وقع أثناء عملية تحديث لأحد الملفات، فالتغيير الوحيد الذي طرأ على نظام ملفات EXT هو إضافة السجلات أو الصحائف (<a href="https://en.wikipedia.org/wiki/Journaling_file_system" rel="external nofollow">journal</a>) التي تُخزِّن التعديلات مسبقًا قبل إجرائها على نظام الملفات؛ أما بقية بنية القرص فبقيت تماثل بنية نظام ملفات EXT2.<br>
	بدلًا من كتابة البيانات إلى كتل البيانات على القرص مباشرةً كما في الإصدارات السابقة، فإن السجلات في نظام ملفات EXT3 تكتب بيانات الملف –إضافةً إلى البيانات الوصفية– إلى مكان مُحدَّد في القرص، وبعد أن تكتب البيانات بأمان على القرص، فيمكن أن تُدمَج أو تُضاف إلى الملف الهدف باحتمال فقدان البيانات بنسبة تقترب من الصفر.<br>
	وبعد كتابة البيانات إلى كتل البيانات على القرص، فسيُحدَّث السجل (journal) لكي يبقى نظام الملفات بحالة مستقرة في حال حدوث فشل في النظام قبل كتابة جميع البيانات الموجودة في السجل على القرص.<br>
	سيتحقق نظام الملفات من وجود تضاربات عند الإقلاع، وستُكتَب البيانات الموجودة في السجل إلى كتل البيانات الموجودة في القرص لإكمال التحديثات التي تستهدف ملفًا معينًا.<br>
	يُنقِص استخدام السجلات من أداء كتابة البيانات، لكن هنالك ثلاثة خيارات متوافرة للسجلات التي تسمح للمستخدم بالاختيار بين الأداء وسلامة البيانات والحماية. أفضِّل سلامة البيانات على الأداء في الأنظمة التي أعمل عليها لعدم وجود نشاطات تحتوي على الكثير من الكتابة على الأقراص.<br>
	تقلل ميزة السجلات من الوقت اللازم لتفحص القرص الصلب والبحث عن التضاربات بعد حدوث انهيارات من ساعات (أو حتى أيام) إلى دقائق قليلة (في أقصى الحالات).<br>
	واجهتُ مشاكل كثيرة على مر السنين التي أدت إلى انهيار أنظمتي؛ لن أذكرها بالتفصيل لأن ذكرها سيتطلب كتابة مقالة كاملة، لكن يكفي القول أنَّ أغلبها قد حدث دون تدخل من المستخدم، كحدوث انقطاع في الكهرباء؛ ولحسن الحظ، قلَّلت أنظمة ملفات EXT التي تستعمل السجلات من زمن الاستعادة إلى حوالي الدقيقتين أو ثلاث دقائق؛ أضف إلى ذلك أنَّني لم أواجه مشاكل مع فقدان البيانات منذ استعمالي لنظام ملفات EXT3.<br>
	ميزة السجلات الموجودة في EXT3 يمكن تعطيلها وسيعمل نظام الملفات مثل EXT2، لكن سيبقى السجل موجودًا إلا أنه فارغٌ وغير مستعمل. كل ما عليك فعله هو إعادة وصل (remount) القسم باستخدام الأمر <code>mount</code> مع تمرير خيار له لتحديد نوع نظام الملفات إلى EXT2. قد تتمكن من فعل ذلك من سطر الأوامر، اعتمادًا على نظام الملفات الذي تعمل عليه، لكن يمكنك تعديل الراية <code>type</code> في ملف <code>‎/etc/fstab</code> ثم تعيد إقلاع النظام. لا أنصحك بتاتًا بإعادة وصل نظام ملفات EXT3 كنظام ملفات EXT2 لأن ذلك سيجعل نظام ملفاتك عرضةً لفقدان البيانات وستأخذ عملية استعادته وقتًا أطول.<br>
	يمكن تحديث نظام ملفات EXT2 موجود مسبقًا إلى EXT3 بإضافة سجل (journal) باستعمال الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_2712_9">
tune2fs -j /dev/sda1</pre>

<p>
	حيث <code>‎/dev/sda1</code> هو مُعرِّف القرص والقسم الذي تريد تحديثه؛ احرص على تعديل نوع نظام الملفات عبر تعديل قيمة الراية <code>type</code> في ملف <code>‎/etc/fstab</code> وإعادة وصل ذاك القسم أو إعادة إقلاع النظام لتأخذ التعديلات مجراها.
</p>

<h2 id="ext4">
	EXT4
</h2>

<p>
	يُحسِّن <a href="https://en.wikipedia.org/wiki/Ext4" rel="external nofollow">نظام ملفات EXT4</a> من الأداء والموثوقية والقدرة التخزينية. فلتحسين الموثوقية (reliability) أضيفت بيانات وصفية وتدقيق لمجموع السجلات (journal checksums)؛ ولتحقيق متطلبات أنظمة المهام الحرجة (mission-critical) فتم تحسين بصمات الوقت لنظام الملفات لجعلها تُخزِّن بدقة تصل إلى النانو ثانية، وحُلَّت مشكلة «<a href="https://en.wikipedia.org/wiki/Year_2038_problem" rel="external nofollow">عام 2038</a>» حتى عام 2446.<br>
	تحولت آلية حجز البيانات من كتل ثابتة الحجم إلى امتدادات (extents)، إذ يمكن وصف الامتداد بأنه بداية ونهاية مكان موجود على القرص الصلب، وهذا يجعل من الممكن توصيف ملفات طويلة ومستمرة (فيزيائيًا) في مؤشر فهرسة وحيد، والذي يقلل عدد المؤشرات المطلوبة لوصف مكان تخزين جميع البيانات في الملفات الكبيرة؛ ويُطبِّق نظام ملفات EXT4 استراتيجيات لتوزيع البيانات التي تحرص على تقليل تجزئة الملف قدر المستطاع.<br>
	يُقلِّل نظام ملفات EXT4 من تجزئة الملفات عبر جعل الملفات المُنشَأة حديثًا منتشرةً على القرص وليست متجمعةً في مكانٍ وحيدٍ في بداية القرص كما كانت تفعل أنظمة الملفات القديمة.<br>
	تحاول خوازميات حجز مساحة الملفات أن تخزن الملفات بانتظام قدر الإمكان على المجموعات الأسطوانية، وإذا كان من الضرورية تجزئة الملف فستحاول جعل تلك القطع قريبةً من بعضها فيزيائيًا لتقليل زمن التأخير الناتج عن حركة رأس القراءة.<br>
	هنالك استراتيجيات أخرى تستعمل لحجز مساحة تخزينية أكبر من اللازمة عند إنشاء الملفات الجديدة أو إضافة بيانات إلى ملفات موجودة مسبقًا، وهذا يساعد في زيادة مساحة الملف دون تجزئته إلى أكثر من جزء؛ أضف إلى ذلك أنَّ الملفات الجديدة لا توضع مباشرةً بعد الملفات الموجودة مسبقًا مما يمنع تجزئة الملفات الموجودة مسبقًا.<br>
	وبوضع مكان التخزين على القرص الفيزيائي جانبًا: يستعمل نظام الملفات EXT4 عدِّة استراتيجيات مثل تأخير حجز المساحة للسماح لنظام الملفات بجمع جميع البيانات التي ستكتب على القرص قبل حجز المساحة التخزينية لها، مما يُحسِّن من احتمال حجز مساحة تخزينية متجاورة أو مستمرة.<br>
	يمكن أن توصل (mount) أنظمة ملفات EXT القديمة مثل EXT2 و EXT3 كنظام ملفات EXT4 لتحسين الأداء قليلًا، لكن هذا يعني تعطيل بعض من أهم الميزات الجديدة لنظام ملفات EXT4، لذا لا أستحسن فعل ذلك.<br>
	أصبح نظام ملفات EXT4 افتراضيًا في توزيعة فيدورا بدءًا من الإصدار 14؛ ويمكن تحديث نظام ملفات EXT3 إلى EXT4 باتباع التعليمات الواردة في <a href="https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ext4converting.html" rel="external nofollow">توثيق فيدورا</a>، لكن لن يكون الأداء ممتازًا بسبب بنى البيانات الوصفية لنظام EXT3 التي ما تزال موجودةً؛ وأفضل طريقة برأيي لتحديث نظام ملفات EXT3 إلى EXT4 هي أخذ نسخة احتياطية لجميع البيانات في القسم الذي تحاول ترقية نظام ملفاته، ثم استخدام الأمر <code>mkfs</code> لإنشاء نظام ملفات EXT4 فارغ في القسم، ثم استعادة جميع البيانات من نسخة احتياطية.
</p>

<h2 id="inode">
	inode
</h2>

<p>
	مؤشر الفهرسة –كما شرحناه سابقًا– هو مكوِّن مهم من البيانات الوصفية في أنظمة EXT، يُظهِر الشكل الآتي العلاقة بين مؤشر الفهرسة وبين البيانات المخزنة على القرص الصلب، وفي هذه الحالة كانت البيانات مجزئة، لذا من غير المرجح أن تشاهد ملفًا موزعًا على كتل بيانات كثيرة، وفي الحقيقة تجزئة الملفات في أنظمة ملفات EXT قليلة جدًا كما سترى في بقية هذا القسم، لذا ستستخدم أغلبية مؤشرات الفهرسة مؤشرًا أو مؤشرين مباشرين إلى البيانات ولن تستعمل أيّة مؤشرات غير مباشرة.
</p>

<p style="text-align: center;">
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="25363" data-unique="do67u3yai" src="https://academy.hsoub.com/uploads/monthly_2017_11/2-inodesanddataallocation-01_0.png.8f4d849d92f4187f27b93c29e712e0d1.png" alt="2-inodesanddataallocation-01_0.png"></p>

<p>
	لا يحتوي مؤشر الفهرسة على اسم الملف، فالوصول إلى الملف يتم عبر قيود المجلد (directory entry)، وقيمة ذلك المؤشر هي رقم مؤشر الفهرسة، وكل مؤشر فهرسة في نظام الملفات له مُعرِّف ID ذي رقم فريد، لكن يمكن لمؤشرات الفهرسة الموجودة في أقسام أخرى على القرص الفيزيائي نفسه أو على الحاسوب نفسه أن تملك المعرف الفريد ذاته. وهذا ما يؤثر على <a href="https://en.wikipedia.org/wiki/Hard_link" rel="external nofollow">الوصلات الصلبة</a> (hard links)، لكن هذا النقاش خارج عن نطاق هذا الدرس.<br>
	يحتوي مؤشر الفهرسة على البيانات الوصفية التابعة للملف، بما في ذلك نوعه والأذونات المسندة إليه وحجمه التخزيني، ويحتوي مؤشر الفهرسة على مساحة لخمسة عشر مؤشرًا التي تصف مكان وطول كتل البيانات الموجودة في قسم البيانات من المجموعة الأسطوانية، ويوفر اثنا عشر مؤشرًا منها وصولًا مباشرًا إلى كتل البيانات ويجب أن تكون كافيةً للتعامل مع معظم الملفات؛ لكن للملفات المجزأة كثيرًا، فمن الضروري الحصول على إمكانيات إضافية على شكل مؤشرات غير مباشرة، ولا تعد هذه المؤشرات على أنها مؤشرات فهرسة (inode)، لذا سأطلق عليها مصطلح «مؤشر» (node) للتفريق بينهما.<br>
	المؤشر غير المباشر هو كتلة بيانات عادية في نظام الملفات التي تستخدم لوصف البيانات وليس لتخزين البيانات الوصفية، وبالتالي يمكن دعم أكثر من خمس عشرة مدخلةً (entries). فمثلًا، إذا كانت كتلة البيانات بحجم 4 كيلوبايت فيمكنها أن تدعم 512 مؤشرًا غير مباشر ذا 4 بايتات، مما يسمح باستعمال 12 مؤشرًا مباشرًا و 512 مؤشرًا غير مباشر = 524 مؤشرًا للملف الواحد. يجدر بالذكر أنَّ استعمال مؤشرين أو ثلاثة مؤشرات غير مباشرة هو أمرٌ مدعوم، لكن ليس من المرجح أن تصدف هذه الحالة معنا.
</p>

<h2 id="تجزئة-البيانات">
	تجزئة البيانات
</h2>

<p>
	كانت تجزئة البيانات في أنظمة ملفات الحواسيب القديمة مثل FAT (بمختلف إصداراته) و NTFS مشكلةً كبيرةً تؤدي إلى أداء منخفض للأقراص، وأصبحت عملية إلغاء التجزئة محط أنظار الشركات وانتشرت برمجيات لإلغاء التجزئة تتراوح بين البرمجيات الفعالة جدًا إلى البرمجيات الشكلية.<br>
	أنظمة الملفات المستعملة في لينكس تستعمل استراتيجيات تساعد في تقليل تجزئة الملفات الموجودة في القرص الصلب وتقلل تأثير التجزئة عندما تحدث.<br>
	يمكنك استعمال الأمر <code>fsck</code> على أنظمة ملفات EXT للتحقق من حالة تجزئة نظام الملفات الكلية؛ فالمثال الآتي يتفحص مجلد المنزل لجهازي الشخصي، الذي كانت نسبة التجزئة فيه حوالي 1.5% فقط. احرص على تمرير المعامل <code>‎-n</code> لأنه يمنع <code>fsck</code> من اتخاذ أي إجراء على نظام الملفات التي يتفحصه.
</p>

<pre class="ipsCode" id="ips_uid_9423_8">
fsck -fn /dev/mapper/vg_01-home
</pre>

<p>
	أجريتُ بعض الحسابات النظرية لتحديد إذا ما كانت عملية إلغاء تجزئة القرص ستسبب في تحسين ملحوظ للأداء؛ وصحيحٌ أنني افترضت بعض الفرضيات، وأخذتُ بيانات أداء القرص من قرص جديد من نوع Westren Digital بسعة 300 غيغابايت ذي زمن تحريك بين المسارات يقدر بقيمة 2 ملي ثانية؛ وكان عدد الملفات في هذا الملف مساويًا لعدد الملفات الموجودة في نظام في اليوم الذي أجريتُ فيه هذه الحسابات، وافترضتُ نسبةً كبيرةً من الملفات المجزئة (20%) التي ستجرى عليها عمليات يوميًا.
</p>

<center>
	<table border="1"><tbody>
<tr>
<td style="padding: 5px 10px;">
					<strong>عدد الملفات الكلي</strong>
				</td>
				<td style="padding: 5px 10px;">
					<strong>271,794</strong>
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					نسبة التجزئة
				</td>
				<td style="padding: 5px 10px;">
					5.00%
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					الانقطاعات
				</td>
				<td style="padding: 5px 10px;">
					13,590
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					 
				</td>
				<td style="padding: 5px 10px;">
					 
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					نسبة الملفات المجزئة التي ستجرى عليها عمليات يوميًا
				</td>
				<td style="padding: 5px 10px;">
					20% (فرضًا)
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					عدد حركات البحث الإضافية
				</td>
				<td style="padding: 5px 10px;">
					2,718
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					متوسط زمن البحث
				</td>
				<td style="padding: 5px 10px;">
					10.90 ملي ثانية
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					زمن البحث الإضافي اليومي
				</td>
				<td style="padding: 5px 10px;">
					29.63 ثانية
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					 
				</td>
				<td style="padding: 5px 10px;">
					0.49 دقيقة
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					 
				</td>
				<td style="padding: 5px 10px;">
					 
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					زمن الانتقال من مسار إلى آخر
				</td>
				<td style="padding: 5px 10px;">
					2.00 ملي ثانية
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					زمن الانتقال الإضافي اليومي
				</td>
				<td style="padding: 5px 10px;">
					5.44 ثانية
				</td>
			</tr>
<tr>
<td style="padding: 5px 10px;">
					 
				</td>
				<td style="padding: 5px 10px;">
					0.091 دقيقة
				</td>
			</tr>
</tbody></table>
</center>

<p>
	أجريتُ عمليتَي حساب لزمن البحث الإضافي اليومي، مرةً اعتمادًا على زمن الانتقال من مسار إلى آخر، وهذه هي الحالة الشائعة لأغلبية الملفات بسبب استراتيجيات تخزين الملفات التي تستعملها أنظمة ملفات EXT؛ ومرةً أخذتُ زمن البحث الإضافي اليومي، وبهذا أكون قد أخذت أسوأ حالة بالحسبان.<br>
	وكما تلاحظ من الجدول السابق، إنَّ أثر التجزئة على أنظمة ملفات EXT الحديثة المستعملة على قرص صلب ذي أداءٍ متواضع هو أثرٌ ضئيل ويهمل لأغلبية حالات الاستخدام.<br>
	يمكنك أن تضع أرقامًا من نظامك في ورقة عمل (spreadsheet) لترى أثر التجزئة في نظامك على الأداء. وصحيحٌ أنَّ العمليات الحسابية السابقة لا تمثِّل الأداء الفعلي، لكن قد تعطيك نظرة عامة عن التجزئة الموجودة في نظام الملفات عندك وأثرها النظري على أداء النظام.<br>
	نسبة التجزئة في أغلبية الأقسام عندي تتراوح بين 1.5% إلى 1.6%؛ لكن لدي قسم نسبة تجزئته هي 3.3% لكنه قسمٌ كبيرٌ بسعة 128 غيغا بايت وفيه أقل من 100 ملف ISO حجمها التخزيني كبير جدًا؛ وكان علي توسعة هذا القسم عدِّة مرات على مر الوقت لأنه كان ممتلئًا طوال الوقت.<br>
	لكن هنالك بعض بيئات العمل التي تتطلب ضمانةً لنسبة تجزئة أقل؛ ويمكن ضبط نظام ملفات EXT من مدير له خبرة ويمكنه تعديل المعاملات لتناسب نمط العمل الملائم. ويمكن فعل ذلك عند إنشاء نظام الملفات أو لاحقًا باستخدام الأمر <code>tune2fs</code>، ويجب أن تُختبَر نتائج كل عملية تعديل، وتُسجَّل النتائج وتُحلَّل للتأكد أنَّ الأداء مثالي في البيئة المستهدفة.<br>
	وفي أسوأ حالة، التي لا يمكن تحسين الأداء فيها إلى الدرجة المطلوبة، فيمكن أن تكون أنظمة الملفات الأخرى ملائمة لنوع الأعمال المطلوب؛ تذكر أنَّ من الشائع استخدام أكثر من نظام ملفات في حاسوب واحد.<br>
	بسبب النسبة الضئيلة من التجزئة في أغلبية أنظمة ملفات EXT، فليس من الضروري إجراء عملية إلغاء تجزئة؛ ولا توجد أداء آمنة لإلغاء التجزئة لأنظمة ملفات EXT؛ لكن هنالك عدِّة أدوات تسمح لك بالتحقق من تجزئة ملف معيّن أو تجزئة بقية المساحة الفارغة في نظام الملفات.<br>
	هنالك أداة باسم <code>e4defrag</code> التي تستطيع إلغاء تجزئة ملف أو مجلد أو نظام ملفات بما تسمح به المساحة الفارغة المتبقية، وكما يوحي اسم هذه الأداة: فهي تعمل على الملفات الموجودة على نظام ملفات EXT4، ولها بعض المحدوديات.<br>
	إذا كان من الضروري إجراء عملية إلغاء تجزئة كاملة لنظام ملفات EXT4، فهنالك طريقة وحيدة عملية ألا وهي نقل جميع الملفات من نظام الملفات الذي تريد إلغاء تجزئته، وتحرص على حذفها حذفًا تامًا بعد أن تُنسَخ بشكل آمن إلى مكانٍ آخر؛ ومن المستحسن زيادة مساحة القسم إن أمكن ذلك، لتجنب حدوث التجزئة مستقبلًا. يمكنك بعد ذلك أن تنسخ الملفات إلى القسم الجديد؛ يجدر بالذكر أنَّ الطريقة السابقة لا تضمن لك إلغاء التجزئة تمامًا.
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	أنظمة ملفات EXT هي أنظمة الملفات المبدئية في أغلبية توزيعات لينكس لأكثر من عشرين عامًا، فهي تتسم بالثبات والموثوقية والأداء ولا تتطلب صيانة إلا قليلًا.<br>
	جربتُ عدِّة أنظمة ملفات لكنني عدتُ دومًا إلى استخدام أنظمة ملفات EXT، وكانت أنظمة ملفات EXT تستعمل في جميع الأماكن التي عملتُ فيها التي تستعمل لينكس، ووجدتها مناسبةً لأغلبية الاستعمالات.<br>
	الخلاصة أنَّ نظام ملفات EXT4 مناسب لأغلبية أنظمة لينكس إلا إذا كان هنالك سببٌ قويٌ يدفعنا لاستخدام نظام ملفات آخر.
</p>

<p>
	ترجمة –وبتصرّف– للمقال <a href="https://opensource.com/article/17/5/introduction-ext4-filesystem" rel="external nofollow">An introduction to Linux’s EXT4 filesystem</a>لصاحبه David Both
</p>
]]></description><guid isPermaLink="false">343</guid><pubDate>Sun, 03 Sep 2017 15:02:00 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645;&#x627;&#x62A; &#x645;&#x62A;&#x642;&#x62F;&#x645;&#x629; &#x644;&#x644;&#x645;&#x62D;&#x631;&#x650;&#x651;&#x631; Sed &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85%D8%A7%D8%AA-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%84%D9%84%D9%85%D8%AD%D8%B1%D9%90%D9%91%D8%B1-sed-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r322/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_06/main.png.e9d7d262a117b7b50af8766bbff53c0b.png" /></p>

<h2 id="تمهيد">
	تمهيد
</h2>

<p>
	المُحرِّر التدفقي sed هو أداةٌ قويةٌ جدًا لتعديل النصوص، حيث تستطيع باستخدامها معالجة النصوص بجهدٍ بسيط. ناقشنا في الدرس السابق <a href="https://academy.hsoub.com/devops/linux/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%AA%D8%AF%D9%81%D9%82%D9%8A-sed-%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r318/" rel="">أساسيات استخدام المحرر Sed</a>، وسنكمل مشوارنا في هذا الدرس بشرح بعض المواضيع المتقدمة.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23813" data-unique="3gnhua7wo" src="https://academy.hsoub.com/uploads/monthly_2017_06/main.png.c890426187726b707bf7b073505a952e.png"></p>

<h2 id="إمكانية-تطبيق-تغييرات-عدة-معا">
	إمكانية تطبيق تغييرات عِدّة معا
</h2>

<p>
	هنالك حالاتٌ ترغب فيها بتمرير أوامر <code>sed</code> عِدّة في الوقت نفسه، وهنالك طرائق عدّة لفعل ذلك.<br>
	إذا لم تتوافر عندك الملفات التي عملنا عليها في الدرس السابق، فيمكنك تطبيق هذه الأوامر لإنشائها لكي نعدِّلها في سياق هذا الدرس:
</p>

<pre class="ipsCode" id="ips_uid_6720_8">
cd
cp /usr/share/common-licenses/BSD .
cp /usr/share/common-licenses/GPL-3 .
echo "this is the song that never ends
yes, it goes on and on, my friend
some people started singing it
not knowing what it was
and they'll continue singing it forever
just because..." &gt; annoying.txt</pre>

<p>
	ولقدرة تعامل الأمر <code>sed</code> مع مجرى الإدخال والإخراج القياسي، فيمكننا استدعاء الأمر sed أكثر من مرة عبر استعمال الأنابيب (pipes، وذلك عبر رمز الخط الشاقولي <code>|</code>). تذكر أنَّ عليك تخليص (escape) المحرف <code>&amp;</code> لأنَّه يحمل معنىً خاصًا في <code>sed</code>:
</p>

<pre class="ipsCode" id="ips_uid_6720_10">
sed 's/and/\&amp;/' annoying.txt | sed 's/people/horses/'</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_12">
this is the song that never ends
yes, it goes on &amp; on, my friend
some horses started singing it
not knowing what it was
&amp; they'll continue singing it forever
just because…</pre>

<p>
	لقد نجحت محاولتنا، لكنّ ذلك غير عملي لأننا استدعينا الأمر <code>sed</code> مرات عدّة، وهو أطول، ولن نستفيد من ميزات <code>sed</code> المبنية داخله…<br>
	يمكننا إرسال مختلف التعليمات إلى الأمر <code>sed</code> باستخدام الخيار <code>‎-e</code> قبل كل تعليمة. سنُعيد كتابة الأمر السابق وسنستخدم فيه الخيار <code>‎-e</code>:
</p>

<pre class="ipsCode" id="ips_uid_6720_14">
sed -e 's/and/\&amp;/' -e 's/people/horses/' annoying.txt</pre>

<p>
	طريقةٌ أخرى لتنفيذ تعليمات <code>sed</code> عدّة معًا هي استعمال الفاصلة المنقوطة <code>;</code> لفصل التعليمات عن بعضها. وهذا شبيهٌ بالأمر السابق لكن دون الحاجة إلى استعمال الخيار <code>‎-e</code>:
</p>

<pre class="ipsCode" id="ips_uid_6720_16">
sed 's/and/\&amp;/;s/people/horses/' annoying.txt</pre>

<p>
	لاحظ عند استخدامنا للخيار <code>‎-e</code> أننا احتجنا إلى تضمين التعليمات المختلفة داخل علامتَي اقتباس؛ لكن عندما فصلنا التعليمات عبر الفاصلة المنقوطة فوضعناها جميعًا ضمن سلسلة نصية وحيدة محاطة بعلامتَي اقتباس فقط.<br>
	وعلى الرغم من أنَّ الطريقتين السابقتين المستعملتين لتنفيذ تعليمات عدّة معًا مفيدتان، لكن هنالك حالات نضطر فيها إلى تمرير ناتج أحد أوامر <code>sed</code> إلى الآخر عبر أنبوب.<br>
	خذ مثلًا المعامل <code>=</code>، الذي يُضيف رقم السطر في سطر جديد قبله. أمعن النظر في ناتج الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_6720_18">
sed '=' annoying.txt</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_20">
1
this is the song that never ends
2
yes, it goes on and on, my friend
3
some people started singing it
4
not knowing what it was
5
and they'll continue singing it forever
6
just because…</pre>

<p>
	إذا أردنا تغيير تنسيق الأرقام عبر تعديل النص، فسنجد أنَّ ذلك لا يعمل كما نتوقع.<br>
	لشرح هذه الفترة، سنتعلم قليلًا عن التعليمة <code>G</code> التي تُضيف سطرا فارغا بين كل سطرين مبدئيًّا (استخدام هذه التعليمة أكثر تعقيدًا مما سبق، لكننا سنتعلمها لاحقًا):
</p>

<pre class="ipsCode" id="ips_uid_6720_22">
sed 'G' annoying.txt</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_24">
this is the song that never ends

yes, it goes on and on, my friend

some people started singing it

not knowing what it was

and they'll continue singing it forever

just because…</pre>

<p>
	إذا دمجنا بين هذين الأمرين، فسنتوقع إضافة سطر فارغ بين كل سطر عادي وسطر يحتوي رقمًا، لكننا سنحصل على ناتجٍ مختلف:
</p>

<pre class="ipsCode" id="ips_uid_6720_26">
sed '=;G' annoying.txt</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_28">
1
this is the song that never ends

2
yes, it goes on and on, my friend

3
some people started singing it

4
not knowing what it was

. . .
. . .</pre>

<p>
	ما حدث هو أنَّ المعامل <code>=</code> عدّل مجرى الإخراج مباشرة، وهذا يعني أننا لا نستطيع التعديل على الناتج؛ لكن يمكننا الالتفاف على هذه الإشكالية عبر استدعاء الأمر <code>sed</code> مرتين، مُمرِّرين ناتج أوّل أمر إلى ثاني أمر عبر أنبوب:
</p>

<pre class="ipsCode" id="ips_uid_6720_30">
sed '=' annoying.txt | sed 'G'</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_32">
1

this is the song that never ends

2

yes, it goes on and on, my friend

3

some people started singing it
. . .
. . .</pre>

<p>
	سنحصل الآن على الناتج الذي كنّا نتوقعه. أبقِ في ذهنك أنَّ بعض التعليمات تسلك هذا السلوك نفسه، وأتوقع أنَّك ستلاحظ ذلك مباشرةً عندما يختلف الناتج عمّا تتوقعه.
</p>

<h2 id="طرائق-متقدمة-لتحديد-المجالات">
	طرائق متقدمة لتحديد المجالات
</h2>

<p>
	إحدى ميزات استخدام المجالات (أو العناوين) في <code>sed</code> هي إمكانية استخدام التعابير النمطية معيارًا لتحديد الأسطر التي ستُطبَّق عليها التعليمات، وهذا يعني أننا لسنا محدودين بإمكانية إجراء التعديلات على الأسطر ذات القيمة المعلومة مسبقًا، كما تعلمنا في الدرس السابق:
</p>

<pre class="ipsCode" id="ips_uid_6720_34">
sed '1,3s/.*/Hello/' annoying.txt</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_36">
Hello
Hello
Hello
not knowing what it was
and they'll continue singing it forever
just because…</pre>

<p>
	يمكننا –بدلًا مما سبق– استعمال <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D9%86%D9%85%D8%B7%D9%8A%D8%A9-regular-expressions-r63/" rel="">التعابير النمطية</a> لمطابقة الأسطر التي تحتوي أنماطًا معيّنةً، ويمكننا فعل ذلك بوضع تعبير المُطابَقة بين خطين مائلين <code>/</code> قبل البدء بتعريف تعليمات التعديل، كما في المثال الآتي:
</p>

<pre class="ipsCode" id="ips_uid_6720_38">
sed '/singing/s/it/&amp; loudly/' annoying.txt</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_40">
this is the song that never ends
yes, it goes on and on, my friend
some people started singing it loudly
not knowing what it was
and they'll continue singing it loudly forever
just because…</pre>

<p>
	وضعنا في المثال السابق الكلمة «loudly» بعد أوّل كلمة «it» في كل سطر يحتوي على السلسلة النصية «singing»، لاحظ أنَّ السطرين الثاني والرابع لم يُعدَّلا لعدم مطابقتهما للتعبير.
</p>

<p>
	قد تمسي التعابير التي تستعمل لتحديد مجالات الأسطر التي ستُنفَّذ عليها التعليمات معقدةً جدًا، لكن ذلك يوفِّر قدرًا كبيرًا من المرونة عند تنفيذ التعليمات.<br>
	المثال الآتي ليس معقدًا أبدًا، لكنه يوضِّح كيف يمكن استخدام التعابير النمطية لتحديد مجالات لتُستعمَل مع تعليماتٍ أخرى. هذا التعبير يُطابِق أيّة أسطر فارغة (التعبير النمطي يُطابِق بداية السطر متبوعةً مباشرةً بنهاية السطر) ومن ثم تمرير هذه المجال من الأسطر إلى تعليمة الحذف:
</p>

<pre class="ipsCode" id="ips_uid_6720_42">
sed ‘/^$/d’ GPL-3</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_44">
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007
 Copyright (C) 2007 Free Software Foundation, Inc. 
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.
                            Preamble
  The GNU General Public License is a free, copyleft license for
. . .
. . .</pre>

<p>
	أبقِ في ذهنك أنَّنا نستطيع استعمال التعابير النمطية لتحديد بداية المجال ونهايته؛ فمثلًا، يمكننا حذف جميع الأسطر التي تأتي بعد سطرٍ يحتوي الكلمة «START» حتى يأتي سطرٌ فيه الكلمة «END» بتنفيذ الأمر:
</p>

<pre class="ipsCode" id="ips_uid_6720_46">
sed '/^START$/,/^END$/d' inputfile</pre>

<p>
	لكن عليك أن تنتبه أنَّ الأمر السابق سيحذف كل شيء بدءًا من أوّل <code>START</code> انتهاءً بأول <code>END</code>، ثم سيُكرِّر عملية الحذف إذا ظهرت الكلمة <code>START</code> مرةً أخرى.
</p>

<p>
	إذا أردتَ عكس المجال (أي تنفيذ التعلميات على الأسطر التي لا تُطابِق النمط)، فيمكنك اتباع النمط بعلامة التعجب <code>!</code>؛ فمثلًا، يمكننا حذف جميع الأسطر غير الفارغة (أعلمُ أنَّ هذا ليس مفيدًا، لكنني أعرضه هنا مثالًا) باستعمال الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_6720_48">
sed '/^$/!d' GPL-3</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_50">
 </pre>

<p>
	لاحظ أنَّ بإمكانك استعمال علامة التعجب لعكس مجال التحديد على أي نوع من المجالات كالمجالات الرقمية، وليست حكرًا على التعابير النمطية فقط.
</p>

<h2 id="استخدام-ذاكرة-التخزين-hold-buffer">
	استخدام ذاكرة التخزين (Hold Buffer)
</h2>

<p>
	إحدى الميزات التي تزيد من قابلية استخدام <code>sed</code> لإجراء تعديلات على أسطر عدّة معًا تسمى «ذاكرة التخزين» (Hold Buffer)، وهي مكانٌ مؤقتٌ لتخزين النصوص التي يمكن تعديلها من تعليمات عدّة.<br>
	وجود هذه الذاكرة يعني أننا نستطيع تخزين بعض الأسطر أثناء عملنا على أسطرٍ أخرى، ويمكننا إجراء العمليات على كلٍّ منها عند الحاجة.
</p>

<p>
	هذه هي التعليمات التي تستخدم مع ذاكرة التخزين:
</p>

<ul>
<li>
		<code>h</code>: نسخ السطر المُطابَق (والذي نعمل عليه حاليًا) إلى ذاكرة التخزين (مما يؤدي إلى حذف المحتوى الذي كان موجودًا في ذاكرة التخزين).
	</li>
	<li>
		<code>H</code>: إضافة السطر المُطابَق إلى ذاكرة التخزين في نهايتها، وسيُوضَع قبله محرف السطر الجديد <code>‎\n</code>.
	</li>
	<li>
		<code>g</code>: وضع محتويات ذاكرة التخزين مكان السطر المُطابَق (مما يؤدي إلى حذفه).
	</li>
	<li>
		<code>G</code>: إضافة محتويات ذاكرة التخزين إلى السطر المُطابَق مع فصلهما بمحرف السطر الجديد <code>‎\n</code>.
	</li>
	<li>
		<code>x</code>: التبديل بين السطر المُطابَق وذاكرة التخزين.
	</li>
</ul>
<p>
	لنستكشف هذه الفكرة عبر تفحّص أحد الأمثلة المعقدة قليلًا.<br>
	هذا المثال يبيّن كيفية دمج الأسطر المتجاورة مع بعضها بعضًا (في الواقع، يملك <code>sed</code> تعليمةً لفعل ذلك بسهولة وهي التعليمة <code>N</code> التي تدمج كل سطر إلى السطر الذي يسبقه، لكننا سنفعل ذلك يدويًا للتدرّب):
</p>

<pre class="ipsCode" id="ips_uid_6720_52">
sed -n '1~2h;2~2{H;g;s/\n/ /;p}' annoying.txt</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_54">
this is the song that never ends yes, it goes on and on, my friend
some people started singing it not knowing what it was
and they'll continue singing it forever just because…</pre>

<p>
	الأمر السابق يبدو مخيفًا! لنقسِّمه إلى أجزاء ليسهل فهمه.
</p>

<p>
	أوّل شيء علينا ملاحظته هو أننا استعملنا الخيار <code>‎-n</code> لإيقاف طباعة الأسطر تلقائيًا، مما يؤدي إلى عدم طباعة أيّة أسطر إلا التي نطلب من <code>sed</code> إخراجها.<br>
	أوّل جزء من التعليمة هو <code>‎1~2h</code> وأوّل قسم منها هو مجالٌ من الأسطر والذي يعني أنَّ على <code>sed</code> تنفيذ التعليمات على الأسطر ذات الأرقام الفردية بدءًا من السطر الأول (أي تخطي سطر بين كل سطرين)؛ أما <code>h</code> فهي تعليمة نسخ الأسطر المُطابَقة إلى ذاكرة التخزين.<br>
	الجزء الثاني من التعليمة أكثر تعقيدًا، حيث يبدأ بمجال يُحدِّد الأسطر ذات الأرقام الزوجية (أي عكس المجال السابق).<br>
	تُحتوى بقية التعليمة بين قوسين معكوفين، وهذا يعني أنَّ جميع الأوامر الموجودة بين القوسين ستُطبَّق على المجال المُحدَّد؛ وفي حال لم نستعمل الأقواس فستُطبَّق التعليمة <code>H</code> على المجال فقط، وبقية التعليمات ستُنفَّذ على جميع الأسطر.<br>
	التعليمة <code>H</code> ستؤدي إلى نسخ محرف السطر الجديد متبوعًا بالسطر الذي جرت مُطابَقته إلى نهاية ذاكرة التخزين.<br>
	ثم نسخنا ذاكرة التخزين (التي تحتوي على سطرٍ ذي رقمٍ فردي متبوع بمحرف السطر الجديد متبوع بسطرٍ ذي رقمٍ زوجي) مكان السطر المُطابَق، وذلك بالتعليمة <code>g</code>.<br>
	ثم وضعنا فراغًا بدلًا من محرف السطر الجديد، ومن ثم طبعنا الناتج بالتعليمة <code>p</code>.<br>
	وكما ذكرنا آنفًا، استخدام التعليمة <code>N</code> يؤدي إلى تقليل طول الأمر كثيرًا. الأمر التالي يُنتِج الناتج السابق نفسه:
</p>

<pre class="ipsCode" id="ips_uid_6720_56">
sed -n 'N;s/\n/ /p' annoying.txt</pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_6720_58">
this is the song that never ends yes, it goes on and on, my friend
some people started singing it not knowing what it was
and they'll continue singing it forever just because…</pre>

<h2 id="استخدام-سكربتات-sed">
	استخدام سكربتات sed
</h2>

<p>
	إذا بدأت باستخدام التعليمات المعقدة، فستجد أنَّ من الأسهل كتابتها في محرِّرٍ نصي؛ وهذا مفيدٌ جدًا إذا كانت عندك تعليماتٌ كثيرة وأردتَ تطبيقها جميعها على النص نفسه.
</p>

<p>
	على سبيل المثال، إذا كنتَ تكتب رسائلك الإلكترونية في ملفاتٍ نصيةٍ بسيطة، فقد تُجري عليها بعض عمليات المعالجة لتنسيق النص قبل استخدامه، وفي هذه الحالة ستستفيد من كتابة سكربت sed.<br>
	وبدلًا من كتابة أوامر <code>sed</code> كاملة في السكربت، كل ما عليك فعله هو وضع التعليمات في ملف وتمرير هذا الملف كمعطى (argument) إلى <code>sed</code>. أي أنَّ سكربت <code>sed</code> هو قائمة بتعليمات <code>sed</code> فقط (أي الأجزاء التي تضعها عادةً بين علامتي اقتباس مفردتين). مثلًا:
</p>

<pre class="ipsCode" id="ips_uid_6720_60">
s/this/that/g
s/snow/rain/g
1,5s/pinecone/apricot/g</pre>

<p>
	يمكنك بعدئذٍ استخدام السكربت على النحو الآتي:
</p>

<pre class="ipsCode" id="ips_uid_6720_62">
sed -f sedScriptName fileToEdit</pre>

<p>
	تسمح لك سكربتات sed بكتابة جميع تعليمات التعديل في ملفٍ واحد، ثم تنفيذه على الملفات النصية التي ترغب بتنسيقها.
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	أضفنا المزيد من المعلومات عن المُحرِّر sed إلى جعبتنا في هذه المقالة.<br>
	أصدقكَ القول أنَّ تعليمات <code>sed</code> ليست سهلة الفهم من الوهلة الأولى، وعليك تجربتها مرات عدّة لتعتاد استخدامها. ولهذا السبب أنصحك بالتدرّب على إجراء مختلف أنواع التعديلات على النصوص لتحترف استخدام <code>sed</code>.
</p>

<p>
	أرجو أن تكون قد فهمتَ القدرات التي يعطيك إياها المُحرِّر <code>sed</code> عند إجراء تعديلات على النصوص، فكلما ارتقيتَ بمستواك في استخدامه قلَّ الوقت اللازم لإنجاز التعديلات على الملفات النصية.
</p>

<p>
	ترجمة –وبتصرّف– للمقال <a href="https://www.digitalocean.com/community/tutorials/intermediate-sed-manipulating-streams-of-text-in-a-linux-environment" rel="external nofollow">Intermediate Sed: Manipulating Streams of Text in a Linux Environment</a> لصاحبه Justin Ellingwood.
</p>
]]></description><guid isPermaLink="false">322</guid><pubDate>Fri, 23 Jun 2017 16:02:37 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x633;&#x62A;&#x62E;&#x62F;&#x645; &#x627;&#x644;&#x623;&#x645;&#x631; scp &#x644;&#x62A;&#x623;&#x645;&#x64A;&#x646; &#x646;&#x633;&#x62E; &#x627;&#x644;&#x645;&#x644;&#x641;&#x627;&#x62A; &#x628;&#x64A;&#x646; &#x627;&#x644;&#x62E;&#x648;&#x627;&#x62F;&#x64A;&#x645;</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-%D8%A7%D9%84%D8%A3%D9%85%D8%B1-scp-%D9%84%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D9%86%D8%B3%D8%AE-%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AE%D9%88%D8%A7%D8%AF%D9%8A%D9%85-r321/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_06/main2.png.6c6bfe6a5d0c555b6946c50456a33e7f.png" /></p>

<p>
	يعدّ نقل الملفات بين الحاسوب الشخصي وخادوم بعيد أو بين خادوميْن إحدى المهامّ الاعتياديّة لأي مدير أنظمة. توجد الكثير من الوسائل لإنجاز مهمة نقل الملفات هذه، إلا أنّ الأمر <code>scp</code> (اختصار لـ Secure copy، النسخ الآمن) يتميّز عن طرق أخرى ب<a href="https://academy.hsoub.com/programming/general/%D9%85%D8%A7%D9%84%D9%81%D8%B1%D9%82-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AA%D8%B1%D9%85%D9%8A%D8%B2-encoding%D8%8C-%D8%A7%D9%84%D8%AA%D8%B9%D9%85%D9%8A%D8%A9-encryption%D8%8C-%D8%A7%D9%84%D8%AA%D8%AC%D8%B2%D8%A6%D8%A9-hashing-%D9%88%D8%A7%D9%84%D8%AA%D8%B4%D9%88%D9%8A%D8%B4-obfuscation%D8%9F-r308/#%D8%A7%D9%84%D8%AA%D8%B9%D9%85%D9%8A%D8%A9" rel="">تعميّته</a> (تشفيره) للملفات أثناء نقلها. تحمي التعميّةُ الملفاتِ عند النقل من أعين المتطفلين المنتشرين على الشبكة وتساعد في إبقاء محتواها خصوصيا.
</p>

<p style="text-align: center;">
	<img alt="main2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23754" data-unique="2bzoarfnt" src="https://academy.hsoub.com/uploads/monthly_2017_06/main2.png.32af8f5065c43b02b5a213bec21c2148.png"></p>

<p>
	يعتمد الأمر <code>scp</code> على <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr>، لذا تأكّد أنه معدّ جيّدًا. إن كان <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> معدًّا للعمل عن <a href="https://academy.hsoub.com/devops/security/ssh/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D9%88%D8%AE%D9%8A%D8%A7%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%B9%D9%86-%D8%A8%D8%B9%D8%AF-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-ssh-r74/#-ssh-ssh-" rel="">طريق المفاتيح العموميّة والخاصّة</a> فلن تحتاج لإدخال كلمة السّر في كلّ مرة تنفّذ فيها الأمر <code>scp</code>؛ أما إن لم يكن كذلك فستُطلَب منك كلمة السرّ الخاصّة بالحساب المُستخدَم (كما سنرى بعد قليل).
</p>

<p>
	لا يحتاج الأمر <code>scp</code>، عكسَ أدوات أخرى مثل <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%AA%D8%AE%D8%AF%D9%90%D9%85-rsync-%D9%84%D9%85%D8%B2%D8%A7%D9%85%D9%86%D8%A9-%D9%85%D8%AC%D9%84%D9%91%D8%AF%D8%A7%D8%AA-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D9%87%D8%A7%D8%B2-%D8%A7%D9%84%D9%85%D8%AD%D9%84%D9%91%D9%8A-%D9%88%D8%A7%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-r50/" rel=""><code>rsync</code></a>، لتسجيل الدخول إلى الخادوم حتى تُنقَل الملفات.
</p>

<h2 id="نقل-ملف-واحد-من-الجهاز-المحلي-إلى-خادوم">
	نقل ملفّ واحد من الجهاز المحلّي إلى خادوم
</h2>

<p>
	يحتاج الأمر <code>scp</code> للمسار المصدَر والمسار الوِجهة لنسخ ملفّ من مكان إلى آخر. في ما يلي كيفية استخدام الأمر:
</p>

<pre class="ipsCode" id="ips_uid_4536_7">
scp localmachine/path_to_the_file username@server_ip:/path_to_remote_directory
</pre>

<p>
	حيث:
</p>

<ul>
<li>
		<code>localmachine/path_to_the_file</code>: المسار المصدَر (على الجهاز المحلّي).
	</li>
	<li>
		<code>username</code>: حساب المستخدم على الخادوم.
	</li>
	<li>
		<code>server_ip</code>: عنوان IP الخاصّ بالخادوم. يمكن استخدام اسم المضيف أيضا.
	</li>
	<li>
		<code>path_to_remote_directory</code>: المسار الوِجهة (على الخادوم).
	</li>
</ul>
<p>
	مثال على الاستخدام:
</p>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp </span><span class="pun">/</span><span class="pln">home</span><span class="pun">/</span><span class="pln">swapnil</span><span class="pun">/</span><span class="hljs-constant"><span class="typ">Downloads</span></span><span class="pun">/</span><span class="pln">fedora</span><span class="pun">.</span><span class="pln">iso swapnil</span><span class="hljs-variable"><span class="pln">@10</span></span><span class="pun">.</span><span class="hljs-number"><span class="lit">0</span></span><span class="lit">.</span><span class="hljs-number"><span class="lit">0</span></span><span class="pun">.</span><span class="hljs-number"><span class="lit">75</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/media/</span><span class="pln">prim_5</span><span class="pun">/</span><span class="pln">media_server</span><span class="pun">/</span></span></code></pre>

<p>
	بالنسبة لمستخدمي Windows 10 فيمكنهم الاستعانة بـ Ubuntu bash لنسخ ملفات من حاسوب وندوز إلى خادوم لينكس:
</p>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp </span><span class="pun">/</span><span class="pln">mnt</span><span class="pun">/</span><span class="pln">c</span><span class="pun">/</span><span class="hljs-constant"><span class="typ">Users</span></span><span class="pun">/</span><span class="pln">swapnil</span><span class="pun">/</span><span class="hljs-constant"><span class="typ">Downloads</span></span><span class="pun">/</span><span class="pln">fedora</span><span class="pun">.</span><span class="pln">iso swapnil</span><span class="hljs-variable"><span class="pln">@10</span></span><span class="pun">.</span><span class="hljs-number"><span class="lit">0</span></span><span class="lit">.</span><span class="hljs-number"><span class="lit">0</span></span><span class="pun">.</span><span class="hljs-number"><span class="lit">75</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/media/</span><span class="pln">prim_5</span><span class="pun">/</span></span><span class="pln">
  media_server</span><span class="pun">/</span></code></pre>

<h2 id="نسخ-مجلد-محلي-إلى-خادوم">
	نسخ مجلّد محلي إلى خادوم
</h2>

<p>
	إن أردت نسخ مجلّد كامل، بدلا من ملفّ، إلى الخادوم فيمكنك ذلك بإضافة الخيار <code>r-</code> إلى الأمر؛ على النحو التالي:
</p>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp </span><span class="pun">-</span><span class="pln">r localmachine</span><span class="pun">/</span><span class="pln">path_to_the_directory username</span><span class="hljs-variable"><span class="pln">@server_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_remote_directory/</span></span></code></pre>

<p>
	تأكّد من أن المسار المصدر <strong>لا يحوي</strong> شريطا مائلا <code>/</code> في نهايته. في نفس الوقت فإن مسار المجلَّد الوِجهة <strong>يجب</strong> - على عكس المصدر - أن يكون آخره شريطا مائلا.
</p>

<h2 id="نسخ-جميع-ملفات-مجلد-محلي-إلى-الخادوم">
	نسخ جميع ملفات مجلّد محلي إلى الخادوم
</h2>

<p>
	ماذا إن أردت نسخ جميع الملفات الموجودة في مجلّد محلّي إلى مجلّد على الخادوم؟ يمكنك ذلك بإضافة شريط مائل <code>/</code> وعلامة <code>*</code> بعده إلى نهاية مسار المجلّد المصدر؛ دون أن ننسى استخدام الخيار <code>r-</code> مع الأمر <code>scp</code>:
</p>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp </span><span class="pun">-</span><span class="pln">r localmachine</span><span class="pun">/</span><span class="pln">path_to_the_directory</span><span class="com">/* username</span><span class="hljs-variable"><span class="com">@server_ip</span></span><span class="hljs-symbol"><span class="com">:/path_to_remote_directory/</span></span></code></pre>

<p>
	<strong>ملحوظة:</strong> الفرق بين هذا الأمر والأمر السابق أن الأمر الأخير ينسخ ما يحويه المجلّد من ملفّات، بينما ينسخ الأمر السابق المجلّد ومحتوياته معا.
</p>

<h2 id="نسخ-ملفات-من-الخادوم-إلى-الجهاز-المحلي">
	نسخ ملفّات من الخادوم إلى الجهاز المحلّي
</h2>

<p>
	يشبه نسخ ملفات من الخادوم إلى الجهاز المحلّي عموما الطرق المشروحة سابقا، مع تبديل المعطيات - المصدر والوِجهة - المُمرَّرة إلى الأمر.
</p>

<h3 id="نسخ-ملف-واحد">
	نسخ ملف واحد
</h3>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp username</span><span class="hljs-variable"><span class="pln">@server_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_remote_directory</span></span><span class="str"> local_machine/</span><span class="pln">path_to_the_file </span></code></pre>

<h3 id="نسخ-مجلد-من-الخادوم">
	نسخ مجلّد من الخادوم
</h3>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp </span><span class="pun">-</span><span class="pln">r username</span><span class="hljs-variable"><span class="pln">@server_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_remote_directory</span></span><span class="str"> local-machine/</span><span class="pln">path_to_the_directory</span><span class="pun">/</span></code></pre>

<p>
	تأكّد من أن المسار المصدر <strong>لا يحوي</strong> شريطا مائلا <code>/</code> في نهايته. في نفس الوقت فإن مسار المجلَّد الوِجهة <strong>يجب</strong> - على عكس المصدر - أن يكون آخره شريطا مائلا.
</p>

<h3 id="نسخ-جميع-ملفات-مجلد-من-الخادوم">
	نسخ جميع ملفات مجلّد من الخادوم
</h3>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp </span><span class="pun">-</span><span class="pln">r username</span><span class="hljs-variable"><span class="pln">@server_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_remote_directory/</span><span class="pun">*</span></span><span class="pln"> </span><span class="kwd">local</span><span class="pun">-</span><span class="pln">machine</span><span class="pun">/</span><span class="pln">path_to_the_directory</span><span class="pun">/</span><span class="pln"> </span></code></pre>

<h2 id="النسخ-الآمن-للملفات-من-مجلد-على-الخادوم-إلى-مجلد-آخر-على-الخادوم-انطلاقا-من-الحاسوب-المحلي">
	النسخ الآمن للملفات من مجلّد على الخادوم إلى مجلّد آخر على الخادوم انطلاقا من الحاسوب المحلي
</h2>

<p>
	يمكن تسجيل الدخول إلى الخادوم ثم استخدام <code>rsync</code> لإنجاز المهمّة، إلّا أن <code>scp</code> يمكنه فعل ذلك دون الحاجة لتسجيل الدخول إلى الخادوم.
</p>

<h3 id="نسخ-ملف-واحد-1">
	نسخ ملفّ واحد
</h3>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp username</span><span class="hljs-variable"><span class="pln">@server_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_the_remote_file</span></span><span class="str"> username</span><span class="hljs-variable"><span class="str">@server_ip</span></span><span class="hljs-symbol"><span class="str">:/</span></span><span class="pln">
  path_to_destination_directory</span><span class="pun">/</span></code></pre>

<h3 id="نسخ-مجلد">
	نسخ مجلّد
</h3>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp username</span><span class="hljs-variable"><span class="pln">@server_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_the_remote_file</span></span><span class="str"> username</span><span class="hljs-variable"><span class="str">@server_ip</span></span><span class="hljs-symbol"><span class="str">:/</span></span><span class="pln">
  path_to_destination_directory</span><span class="pun">/</span></code></pre>

<h2 id="ملفات-من-خادوم-إلى-خادوم-آخر-انطلاقا-من-الجهاز-المحلي">
	ملفات من خادوم إلى خادوم آخر انطلاقا من الجهاز المحلّي
</h2>

<p>
	تشبه هذه الحالة استخدام <code>scp</code> لنسخ ملفّ من مجلّد على الخادوم إلى مجلّد آخر على نفس الخادوم. الفرق هنا هو أننا نحدّد حساب المستخدم على كلا الخادوميْن وعنوانيْهما أثناء تنفيذ الأمر <code>scp</code> .
</p>

<h3 id="نسخ-ملف-واحد-2">
	نسخ ملف واحد
</h3>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp username</span><span class="hljs-variable"><span class="pln">@server1_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_the_remote_file</span></span><span class="str"> username</span><span class="hljs-variable"><span class="str">@server2_ip</span></span><span class="hljs-symbol"><span class="str">:/</span></span><span class="pln">
  path_to_destination_directory</span><span class="pun">/</span></code></pre>

<h3 id="نسخ-مجلد-1">
	نسخ مجلّد
</h3>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp username</span><span class="hljs-variable"><span class="pln">@server1_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_the_remote_file</span></span><span class="str"> username</span><span class="hljs-variable"><span class="str">@server2_ip</span></span><span class="hljs-symbol"><span class="str">:/</span></span><span class="pln">
  path_to_destination_directory</span><span class="pun">/</span></code></pre>

<h3 id="نسخ-جميع-ملفات-مجلد">
	نسخ جميع ملفات مجلّد
</h3>

<pre class="ipsCode" id="ips_uid_4536_7">
<code class="hljs ruby"><span class="pln">scp </span><span class="pun">-</span><span class="pln">r username</span><span class="hljs-variable"><span class="pln">@server1_ip</span></span><span class="hljs-symbol"><span class="pun">:</span><span class="str">/path_to_source_directory/</span><span class="pun">*</span></span><span class="pln"> username</span><span class="hljs-variable"><span class="pln">@server2_ip</span></span><span class="hljs-symbol"><span class="pun">:/</span></span><span class="pln">
  path_to_the_destination_directory</span><span class="pun">/</span><span class="pln"> </span></code></pre>

<h2 id="خاتمة">
	خاتمة
</h2>

<p>
	تصبح الأمور سهلة كثيرًا فور فهم المبادئ العامة لعمل الأمر <code>scp</code> ، ويمكنك بعدها نسخ الملفات بكل سهولة وأمان.
</p>

<p>
	ترجمة - بتصرّف - للمقال <a href="https://www.linux.com/learn/intro-to-linux/2017/2/how-securely-transfer-files-between-servers-scp" rel="external nofollow">How to Securely Transfer Files Between Servers with scp</a> لصاحبه Swapnil Bhartiya.
</p>
]]></description><guid isPermaLink="false">321</guid><pubDate>Wed, 21 Jun 2017 22:32:11 +0000</pubDate></item><item><title>&#x645;&#x627; &#x627;&#x644;&#x641;&#x631;&#x648;&#x642; &#x628;&#x64A;&#x646; &#x627;&#x644;&#x623;&#x648;&#x627;&#x645;&#x631; grep &#x648;egrep fgrep</title><link>https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D8%A7%D9%84%D9%81%D8%B1%D9%88%D9%82-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%A3%D9%88%D8%A7%D9%85%D8%B1-grep-%D9%88egrep-fgrep-r320/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_06/main.png.14062e55f403d39c317d2b48d4629c59.png" /></p>

<p>
	تشتهر أداة <code>grep</code> بكونها إحدى أدوات البحث الأكثر شهرة في الأنظمة الشبيهة بيونكس Unix-like، سواء تعلّق الأمر بالبحث عن ملفات، سطر أو أسطر عدّة ضمن ملفّ، فهي سريعة وتدعم الكثير من الخيارات مثل: البحث حسب نمط Pattern مكوَّن من سلسلة محارف String والبحث اعتمادًا على تعابير نمطية Regular expressions، بما في ذلك تعابير Perl النمطية Perl reg-ex.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23656" data-unique="wx8q57vyx" src="https://academy.hsoub.com/uploads/monthly_2017_06/main.png.3948399a1b4b326e54ffb13bbfe29758.png"></p>

<p>
	تتوفّر <code>grep</code>، نظرا لتعدّد وظائفها، على عدّة تنويعات تشمل <code>rgrep</code>، <code>pgrep</code>،<code>fgrep</code>، <code>egrep</code> وغيرها. توجد اختلافات يسيرة بين هذه التنويعات تجعل المبرمجين يستخدمون كلّ تنويعة لمهامّ محدّدة حسب رغبتهم وتفضيلهم.
</p>

<p>
	سنعرض في هذا المقال للاختلفات الأساسية بين التنويعات الثلاثة الأكثر شهرة، وهي <code>egrep</code>، <code>grep</code> و<code>fgrep</code>، ومالمتطلبات التي تجعل مستخدمي لينكس يختارون إحداها بدلا من الأخرى.
</p>

<p>
	سنستخدم ملفا بالمحتوى التالي ونسمّيه <code>check_file</code> لتطبيق الأوامر في هذا الدرس عليه.
</p>

<pre class="ipsCode" id="ips_uid_57_7">
grep is a command that can be used on unix-like systems.
it searches for any string in list of strings or file.
It is very fast.
(f|g)ile </pre>

<p>
	<strong>ملحوظة:</strong> لتوافق نتائج تنفيذ الأوامر لديك النتائج المعروضة في هذا الدرس، يجب أن يكون محتوى الملف مطابقا للمحتوى أعلاه: حالة الأحرف +(كبيرة أو صغيرة) وبداية الأسطر. تأكّد كذلك من تنفيذ الأوامر من المجلّد الذي يوجد به الملف، أو اكتب مسار الملف كاملا.
</p>

<h2 id="الأمر-grep">
	الأمر grep
</h2>

<p>
	يعدّ أمر <code>grep</code> الأمر الأساسي في الأنظمة الشبيهة بيونكس للبحث عن مجموعة محارف مهما كان نوعها ضمن سلسلة محارف، ملف، مجموعة ملفات أو ربما <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%A5%D8%B9%D8%A7%D8%AF%D8%A9-%D8%AA%D9%88%D8%AC%D9%8A%D9%87-%D8%A7%D9%84%D8%A5%D8%AF%D8%AE%D8%A7%D9%84%D8%A7%D9%84%D8%A5%D8%AE%D8%B1%D8%A7%D8%AC-io-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r39/" rel="">نتيجة تنفيذ أمر آخر</a>.
</p>

<p>
	يستخدم الأمر <code>grep</code> التعابير النمطية القاعدية Basic Regular Expressions, BRE في البحث؛ علاوة على سلاسل المحارف الاعتيادية. تفقد المحارف الوصفية Meta characters عند استخدام التعابير النمطية القاعدية قدرتها التعبيرية، ويُتَعامل معها كأي محرف عادي؛ إلا إذا سُبِقت بمحرف تخليص Escape (وهو المحرف <code>\</code>).
</p>

<p>
	نرصُد في ما يلي أهم المحارف الوصفية بالنسبة للأمر <code>grep</code>.
</p>

<ul>
<li>
		<code>+</code>: يعني عند تخليصه أننا نبحث عن السلاسل التي يتكرّر فيها المحرف قبله (على يساره) لمرة واحدة على الأقل. يمكن أن توافق العبارةُ <code>a+b</code> سلاسل المحارف <code>ab</code>، <code>aabcd</code>،<code>aaab</code> و<code>aaaab</code>، إلا أنها لا توافق العبارة <code>bcd</code>.
	</li>
	<li>
		<code>?</code>: يشير إلى تكرار المحرف الذي قبله لمرة واحدة على الأكثر، حسب طريقة الاستخدام.
	</li>
	<li>
		<code>(</code>: يشير إلى بدء عبارة تناوب Alternation؛ أي موافقة أحد خيارات يفصل بينها الخط العمودي <code>|</code>.
	</li>
	<li>
		<code>)</code>: يشير إلى نهاية عبارة تناوب Alternation.
	</li>
	<li>
		<code>|</code>: يفصل بين الخيارات ضمن عبارة تناوب. يعني التعبير النمطي التالي <code>(a|b)cde</code> “الحرف <code>a</code> أو الحرف <code>b</code> تتبعه الأحرف <code>cde</code> بهذا الترتيب”؛ أي أن العبارتيْن <code>acde</code> و<code>bcde</code> توافقان التعبير النمطي المذكور.
	</li>
	<li>
		<code>{</code>: يشير هذا المحرف إلى بداية محدّدِ مجال.
	</li>
	<li>
		<code>}</code>: يشير هذا المحرف إلى نهاية محدّد مجال. مثلا؛ تعني العبارة التالية <code>a{2}</code> أننا نبحث عن الحرف <code>a</code> مكررا مرتيْن.
	</li>
</ul>
<p>
	راجع مقال <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D9%86%D9%85%D8%B7%D9%8A%D8%A9-regular-expressions-r63/" rel="">مقدّمة في التعابير النمطية</a> للمزيد عن هذه الدلالات واستخداماتها.
</p>

<p>
	ننفّذ الأمر <code>grep</code> بالطريقتيْن التاليتيْن:
</p>

<pre class="ipsCode" id="ips_uid_57_9">
grep '(f|g)ile' check_file
grep '\(f|g\)ile' check_file</pre>

<p>
	نلاحظ الفرق في النتيجة:
</p>

<p style="text-align: left;">
	<img alt="01_grep.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23653" data-pin-nopin="true" data-unique="sv2870twr" src="https://academy.hsoub.com/uploads/monthly_2017_06/01_grep.png.90312c9b2246c049465089a8e7b6e686.png"></p>

<p>
	يبحث الأمر الأول في الملف <code>check_file</code> عن سلسلة المحارف “<code>(f|g)ile</code>” كما كُتِبت دون أن يُفسّر المحارف <code>(</code>، <code>)</code> و<code>|</code> تفسيرا خاصًّا. ينتُج عن تنفيذ الأمر إظهار الأسطُر التي تحوي سلسلة المحارف المرغوبة، مع عرض السلسلة بلون مغاير؛ حسب الإعدادات (أحمر في حالتي).<br>
	تبدو النتيجة مغايرة بالنسبة للأمر الثاني الذي وضعنا فيه محرف التخليص <code>\</code> أمام كل محرف نريد أن يُفسَّر بدلالته الخاصّة (محرف وصفي)، وليس كمحرف متضمَّن في الجملة التي نبحث عنها. تُصبح دلالة التعبير النمطي المُمرَّر إلى <code>grep</code>: “الكلمات التي يوجد بها أحد الحرفيْن <code>f</code> أو <code>g</code> متبوعا بالأحرف <code>ile</code>“.<br><strong>ملحوظة:</strong> استخدم الخيار <code>o-</code> إن أردتَ إظهار الكلمة التي تطابق التعبير النمطي لوحدها، دون السطر الذي توجد فيه:
</p>

<pre class="ipsCode" id="ips_uid_57_11">
grep -o '(f|g)ile' check_file
grep -o '\(f|g\)ile' check_file</pre>

<h2 id="الأمر-egrep">
	الأمر egrep
</h2>

<p>
	يشبه اﻷمر <code>egrep</code> الأمرَ <code>grep</code> مع فرق أنه يتعامل مع المحارف الوصفية مباشرةً دون الحاجة لمحرف تخليص؛ بمعنى أنه يأخذها بدلالتها الخاصة مباشرةً.
</p>

<p>
	نعيد، لفهم الفكرة جيّدًا، تنفيذَ الأمريْن السابقيْن مع إحلال <code>egrep</code> مكان <code>grep</code>:
</p>

<pre class="ipsCode" id="ips_uid_57_13">
egrep '(f|g)ile' check_file
egrep '\(f|g\)ile' check_file</pre>

<p style="text-align: left;">
	<img alt="02_egrep.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23654" data-pin-nopin="true" data-unique="vtjvfjoq7" src="https://academy.hsoub.com/uploads/monthly_2017_06/02_egrep.png.98bfa11502a4d3ebe993f8f9ea6817b2.png"></p>

<p>
	يبدو الأمر هنا معكوسا: بدون تخليص المحارف الوصفية فإن الأمر <code>egrep</code> يحتفظ بدلالتها الخاصّة، فيبحث في الحالة الأولى عن جميع سلاسل المحارف التي تبدأ بحرف <code>f</code> أو <code>g</code>؛ أما في الحالة الثانية فيعدّ المحارف <code>(</code>، <code>)</code> و<code>|</code> جزءًا من السلسلة ويبحث بالتالي عن العبارة <code>(f|g)ile</code> كما هي.
</p>

<p>
	<strong>ملحوظة:</strong> يشبه تنفيذ الأمر <code>egrep</code> تنفيذَ الأمر <code>grep</code> مع الخيار <code>E-</code>:
</p>

<pre class="ipsCode" id="ips_uid_57_15">
grep -E '(f|g)ile' check_file
grep -E '\(f|g\)ile' check_file</pre>

<p>
	يُفضّل كثيرون استخدام <code>egrep</code> بدلا من <code>grep</code> للبحث اعتمادًا على تعابير نمطيّة إذ أنها تزيح عن كاهلهم ضرورة تخليص المحارف الوصفية؛ خصوصا في العبارات النمطية المعقدة.
</p>

<h2 id="الأمر-fgrep">
	الأمر fgrep
</h2>

<p>
	لا يتعامل الأمر <code>fgrep</code> مع التعابير النمطية ولا المحارف الخاصّة؛ فالمعطى المُمرَّر له أولا هو سلسلة محارف ينبغي البحث عنها كما هي. يشبه استخدام <code>fgrep</code> استخدام الأمر <code>grep</code> مع فرق أن الأخير سيفسّر المحرف <code>\</code> على أنه محرف تخليص، بينما لا يتعرف <code>egrep</code> عليه نهائيا؛ فهو بالنسبة له مجرد محرف كالبقية.
</p>

<pre class="ipsCode" id="ips_uid_57_17">
fgrep '(f|g)ile' check_file
fgrep '\(f|g\)ile' check_file</pre>

<p style="text-align: left;">
	<img alt="03_fgrep.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23655" data-pin-nopin="true" data-unique="62oaso9h0" src="https://academy.hsoub.com/uploads/monthly_2017_06/03_fgrep.png.a8a852dd0ff876e14bc9eef06d512156.png"></p>

<p>
	تمكن ملاحظة أن <code>fgrep</code> بحث في كلتا الحالتيْن عن سلسلة المحارف كما مُرِّرت إليه. في الحالة الأولى كانت النتيجة مشابهة لتنفيذ الأمر <code>grep</code> بدون تخليص المحارف، وفي الثانية أضفنا محرف التخليص <code>\</code>؛ إلا أن <code>fgrep</code> لا يعدّه محرفا ذا دلالة خاصّة فيبحث عن السلسلة كما كُتبت ولا يجدها في الملف.
</p>

<p>
	<strong>ملحوظة:</strong> يشبه تنفيذ الأمر <code>fgrep</code> تنفيذَ الأمر <code>grep</code> مع الخيار <code>F-</code>:
</p>

<pre class="ipsCode" id="ips_uid_57_19">
grep -F '(f|g)ile' check_file
grep -F '\(f|g\)ile' check_file</pre>

<p>
	تعرّفنا في هذا الدرس على الفروق الأساسيّة بين ثلاث تنويعات من الأمر <code>grep</code> شائع الاستخدام في البحث عن سلاسل المحارف. يمكنك اختيار التنويعة التي تناسبك حسب الحاجة.
</p>

<p>
	ترجمة بتصرف لمقال <a href="http://www.tecmint.com/difference-between-grep-egrep-and-fgrep-in-linux/" rel="external nofollow">What’s Difference Between Grep, Egrep and Fgrep in Linux?</a> لصاحبه Gunjit Khera. 
</p>
]]></description><guid isPermaLink="false">320</guid><pubDate>Tue, 13 Jun 2017 17:21:28 +0000</pubDate></item><item><title>&#x623;&#x633;&#x627;&#x633;&#x64A;&#x627;&#x62A; &#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x627;&#x644;&#x645;&#x62D;&#x631;&#x631; &#x627;&#x644;&#x62A;&#x62F;&#x641;&#x642;&#x64A; Sed &#x644;&#x62A;&#x639;&#x62F;&#x64A;&#x644; &#x627;&#x644;&#x646;&#x635;&#x648;&#x635; &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%AA%D8%AF%D9%81%D9%82%D9%8A-sed-%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r318/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.0741dd03afd248757246afafa6ef4771.png" /></p>

<h2 id="تمهيد">
	تمهيد
</h2>

<p>
	المُحرِّر التدفقي <code>sed</code>‏ (Stream EDitor) هو محرِّر نصيّ يُجري عمليات التعديل على المعلومات الآتية من مجرى <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%A5%D8%B9%D8%A7%D8%AF%D8%A9-%D8%AA%D9%88%D8%AC%D9%8A%D9%87-%D8%A7%D9%84%D8%A5%D8%AF%D8%AE%D8%A7%D9%84%D8%A7%D9%84%D8%A5%D8%AE%D8%B1%D8%A7%D8%AC-io-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r39/" rel="">الإدخال القياسي</a> (Standard Input) أو من ملف. يجري المُحرِّر sed عملياته على النصوص سطرًا بسطر بطريقةٍ غير تفاعلية،. هذا يعني إمكانية تحديد التعديلات التي تريد إجراءها أثناء كتابتك للأمر ومن ثم سيُنفِّذها sed تلقائيًا، دون أن يستشيرك في كلّ مرة؛ ربما تجد هذا الموضوع مُربِكًا وغريبًا، لكن اعلم أنَّ هذه الطريقة غير التفاعلية فعّالةٌ جدًا وسريعةٌ لتعديل النصوص.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23385" data-unique="96zbmqirj" src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.4524e5f15b3785681e50679d545bbe02.png"></p>

<p>
	سنشرح في هذا الدرس بعض العمليات الأساسية وسنتعرّف على البنية العامة للتعامل مع هذا المُحرِّر. أنا واثقٌ تمامًا أنَّك لن تستبدل المحرر <code>sed</code> بمحررك النصي العادي، لكن من المرجَّح أن تضيف هذه الأداة الفعّالة إلى جعبة الأدوات التي تستعملها للتعامل مع النصوص.
</p>

<h2 id="أساسيات-استخدام-sed">
	أساسيات استخدام sed
</h2>

<p>
	في الحالة العامة، يُجري المُحِّرر <code>sed</code> عملياته على مجرى نصي (text steam) آتٍ من مجرى الإدخال القياسي أو من ملف. هذا يعني أنَّك تستطيع إرسال ناتج أحد الأوامر إلى الأمر <code>sed</code> مباشرةً لتعديله، أو يمكنك استعمال <code>sed</code> على ملفٍ موجودٍ مسبقا.
</p>

<p>
	عليك أن تتنبّه إلى طباعة الأمر <code>sed</code> لجميع مخرجاته إلى مجرى الإخراج القياسي (Standard output) مبدئيا؛ وهذا يعني طباعة النتائج إلى الشاشة بدلًا من حفظها في ملفٍ ما، إلا إذا أجريت عملية إعادة توجيه (Output redirection).<br>
	الصيغة العامّة لاستخدام هذا المُحرِّر هي:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
sed [options] commands [file-to-edit]</pre>

<p>
	لننسخ بعض الملفات النصية إلى مجلد المنزل الخاص بنا للتدرّب على عمليات التعديل:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs axapta"><span class="pln">cd
cp </span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="pln">share</span><span class="pun">/</span><span class="hljs-keyword"><span class="pln">common</span></span><span class="pun">-</span><span class="pln">licenses</span><span class="pun">/</span><span class="pln">BSD </span><span class="pun">.</span><span class="pln">
cp </span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="pln">share</span><span class="pun">/</span><span class="hljs-keyword"><span class="pln">common</span></span><span class="pun">-</span><span class="pln">licenses</span><span class="pun">/</span><span class="pln">GPL</span><span class="pun">-</span><span class="hljs-number"><span class="lit">3</span></span><span class="pln"> </span><span class="pun">.</span></code></pre>

<p>
	لنستخدم الأمر <code>sed</code> لعرض محتويات ملف رخصة BSD الذي نسخناه آنفًا.<br>
	ولعلمنا أنَّ الأمر <code>sed</code> يُرسِل الناتج إلى الشاشة مبدئيًّا، فيمكننا استخدامه لقراءة الملف دون تعديل، وذلك إذا لم نوفِّر أيّة تعليمات له. لنجرِّب ذلك:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="pln">sed </span><span class="hljs-string"><span class="str">''</span></span><span class="pln"> BSD</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
...
…
</code></pre>

<p>
	يعمل الأمر السابق كما توقعنا لعدم وجود أيّة تعليمات تعديل ضمن علامتَيْ الاقتباس <code>''</code>، مما أدى إلى طباعة كل سطر كما هو إلى مجرى الإخراج القياسي (أي إلى الشاشة).<br>
	سنشرح كيف يستطيع الأمر <code>sed</code> الحصول على النصوص عبر مجرى الإدخال القياسي بتمرير ناتج الأمر <code>cat</code> عبر أنبوب (pipe، باستعمال الرمز <code>|</code>) إلى الأمر <code>sed</code>، وسنلاحظ ظهور الناتج السابق نفسه:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs matlab"><span class="hljs-built_in"><span class="pln">cat</span></span><span class="pln"> BSD </span><span class="pun">|</span><span class="pln"> sed </span><span class="hljs-string"><span class="str">''</span></span></code></pre>

<p>
	المخرجات:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
. . .
. . .
</code></pre>

<p>
	كما لاحظنا، يمكننا إجراء العمليات بسهولة على الملفات أو على مجرى من النص (آتٍ من أحد الأوامر).
</p>

<h2 id="طباعة-أسطر-معينة">
	طباعة أسطر معيّنة
</h2>

<p>
	رأينا في المثال السابق أنَّ تمرير النص إلى الأمر <code>sed</code> دون استخدام أيّة تعليمات تعديل سيؤدي إلى طباعة النتائج مباشرةً إلى مجرى الإخراج القياسي.<br>
	سننظر الآن إلى تعليمة طباعة الأسطر الموجودة في <code>sed</code>، والتي نستطيع استخدامها عبر وضع المحرف <code>p</code> ضمن علامتَي الاقتباس.
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="pln">sed </span><span class="hljs-string"><span class="str">'p'</span></span><span class="pln"> BSD</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>Copyright (c) The Regents of the University of California.
Copyright (c) The Regents of the University of California.
All rights reserved.
All rights reserved.


Redistribution and use in source and binary forms, with or without
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
modification, are permitted provided that the following conditions
are met:
are met:
. . .
. . .
</code></pre>

<p>
	نلاحظ أنَّ <code>sed</code> قد طبع كل سطر مرتين، وهذا بسبب طباعته لكل سطر تلقائيًا، ولأننا طلبنا ذلك مرةً أخرى عبر استعمال تعليمة الطباعة <code>p</code>.
</p>

<p>
	إذا أمعنتَ النظر في الناتج السابق، فستلاحظ أنَّ <code>sed</code> قد طبع أوّل سطر مرتين، متبوعًا بالسطر الثاني مرتين …إلخ. وسترى أنَّ المُحرِّر sed يُجرى عملياته على الأسطر فرادى. حيث يقرأ سطرًا من النص، ثم يجري عمليات التعديل عليه، ثم يخرج النص الناتج قبل تكرار نفس العملية على السطر الذي يليه.<br>
	يمكننا إصلاح الناتج السابق عبر تمرير الخيار <code>‎-n</code> إلى <code>sed</code>، والذي يمنعه من طباعة الأسطر تلقائيًا:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs lasso"><span class="pln">sed </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">'p'</span></span><span class="pln"> BSD</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
. . .
. . .
</code></pre>

<p>
	نلاحظ الآن أنَّ كل سطر طُبِعَ مرةً واحدةً فقط.
</p>

<h2 id="المجالات">
	المجالات
</h2>

<p>
	لا أظن أنَّ الأمثلة السابقة تُحسَب على أنها «تعديلات» (إلا إذا كنت تريد طباعة كل سطر مرتين…)؛ لنعدِّل الآن الناتج بجعل <code>sed</code> يطبع أوّل سطر فقط:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs lasso"><span class="pln">sed </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">'1p'</span></span><span class="pln"> BSD</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>Copyright (c) The Regents of the University of California.
</code></pre>

<p>
	بوضع الرقم <code>1</code> قبل تعليمة الطباعة، فسنخبر <code>sed</code> ما هو السطر الذي نريد إجراء عمليات التعديل عليه. يمكننا أيضًا طباعة أوّل خمسة أسطر (لا تنسَ استخدام الخيار <code>‎-n</code>):
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs lasso"><span class="pln">sed </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">'1,5p'</span></span><span class="pln"> BSD</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
</code></pre>

<p>
	أعطينا مجالًا من الأسطر للأمر <code>sed</code> السابق. وإذا أعطيت <code>sed</code> مجالًا، فهذا يعني رغبتك بإجراء عمليات التعديل على تلك الأسطر فقط. وأخبرنا –في المثال السابق– الأمر <code>sed</code> أن يطبع الأسطر 1 إلى 5. يمكننا تحديد المجال السابق بطريقةٍ أخرى، وذلك بتحديد بداية مجال الأسطر ومن ثم استخدام معامل إزاحة لكي نخبر <code>sed</code> كم سطرًا عليه أن يتنقل للوصول إلى نهاية المجال:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs lasso"><span class="pln">sed </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">'1,+4p'</span></span><span class="pln"> BSD</span></code></pre>

<p>
	سيُنتِج الأمر السابق الناتج نفسه، وذلك لأننا أخبرنا <code>sed</code> أن يبدأ المجال من السطر الأول وينتهي بعده بأربعة أسطر.<br>
	إذا أردنا أن نتخطى سطرًا بين كل سطرين، فيمكننا تحديد «الخطوة» بعد استخدام المحرف <code>~</code>. سنطبع في المثال الآتي سطرًا كل سطرين وذلك بدءًا من السطر 1:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs lasso"><span class="pln">sed </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">n</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">'1~2p'</span></span><span class="pln"> BSD</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>Copyright (c) The Regents of the University of California.

modification, are permitted provided that the following conditions
1. Redistributions of source code must retain the above copyright
2. Redistributions in binary form must reproduce the above copyright
   documentation and/or other materials provided with the distribution.
   may be used to endorse or promote products derived from this software
. . .
. . .
</code></pre>

<h2 id="حذف-الأسطر">
	حذف الأسطر
</h2>

<p>
	يمكننا بسهولة إجراء عمليات حذف للأسطُر بدلًا من طباعتها، وذلك بتبديل الأمر <code>p</code> إلى الأمر <code>d</code>.<br>
	لم نعد نحتاج الخيار <code>‎-n</code> لأنَّ الأمر <code>sed</code> – عند استخدام تعليمة الحذف معه – سيطبع كل شيء لم يُحذَف، مما يساعدنا في معرفة ماذا عُدِّل.<br>
	يمكننا تعديل آخر أمر من القسم السابق ليحذف سطرًا كل سطرين بدءًا من أوّل سطر. يجب أن يظهر في ناتج تنفيذ هذا الأمر كلُّ سطرٍ لم يظهر في ناتج الأمر الذي طبّقناه في القسم السابق:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="pln">sed </span><span class="hljs-string"><span class="str">'1~2d'</span></span><span class="pln"> BSD</span></code></pre>

<p>
	المخرجات:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>All rights reserved.
Redistribution and use in source and binary forms, with or without
are met:
   notice, this list of conditions and the following disclaimer.
   notice, this list of conditions and the following disclaimer in the
3. Neither the name of the University nor the names of its contributors
   without specific prior written permission.
. . .
. . .
</code></pre>

<p>
	من المهم أن تلاحظ أنَّ الملف الأصلي لم يتغيّر قط، فما يزال على حاله، لكن التعديلات التي حدثت قد ظهرت على شاشتنا.<br>
	إذا أردنا حفظ تعديلاتنا، فيمكننا إعادة توجيه مجرى الإخراج القياسي إلى ملفٍ كما في الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="pln">sed </span><span class="hljs-string"><span class="str">'1~2d'</span></span><span class="pln"> BSD </span><span class="pun">&gt;</span><span class="pln"> everyother</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	إذا اطلعتَ على محتويات الملف مستعملًا الأمر <code>cat</code>، فسترى الناتج السابق نفسه. أذكِّرُكَ أنَّ الأمر <code>sed</code> لا يُعدِّل الملف المصدري مبدئيًّا منعًا لحدوث أخطاء.<br>
	يمكننا تغيير هذا السلوك الافتراضي باستعمال الخيار <code>‎-i</code>، الذي يؤدي إلى إجراء التعديلات على الملف الأصلي.<br>
	لنجِّرب هذا الخيار على الملف <code>everyother.txt</code> الذي أنشأناه منذ قليل. لنحاول حذف المزيد من الأسطر من هذا الملف:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs lasso"><span class="pln">sed </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">i</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">'1~2d'</span></span><span class="pln"> everyother</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">txt</span></code></pre>

<p>
	إذا استعملتَ الأمر <code>cat</code> مرةً أخرى، فسترى أنَّ الملف قد عُدِّل.<br>
	وكما ذكرنا سابقًا، الخيار <code>‎-i</code> خطيرٌ ويجب توخي الحذر عند استعماله؛ ولحسن الحظ، يعطينا <code>sed</code> القدرة على إنشاء نسخةٍ احتياطيةٍ مباشرةً قبل التعديل؛ وذلك بوضع لاحقة الملف الاحتياطي مباشرةً بعد الخيار <code>‎-i</code> كما يلي:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs lasso"><span class="pln">sed </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">i</span></span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">bak </span><span class="hljs-string"><span class="str">'1~2d'</span></span><span class="pln"> everyother</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">txt</span></code></pre>

<p>
	الأمر السابق سيؤدي إلى إنشاء ملفٍ احتياطيٍ باللاحقة <code>‎.bak</code>، ثم تعديل الملف الأصلي مباشرةً.
</p>

<h2 id="استبدال-النصوص">
	استبدال النصوص
</h2>

<p>
	أحد أشهر استخدامات المُحرِّر <code>sed</code> هو استبدال النصوص. يملك المُحرِّر <code>sed</code> القدرة على البحث عن أنماطٍ نصيةٍ عبر التعابير النمطية (Regular expressions) ومن ثم استبدال النص المُطابِق.<br>
	يمكنك مراجعة <a href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D9%86%D9%85%D8%B7%D9%8A%D8%A9-regular-expressions-r63/" rel="">هذه المقالة</a> لمزيدٍ من المعلومات حول التعابير النمطية.<br>
	يمكنك استبدال كلمة بأخرى عبر الصيغة البسيطة الآتية:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="hljs-string"><span class="str">'s/old_word/new_word/'</span></span></code></pre>

<p>
	المحرف <code>s</code> يُمثِّل عملية الاستبدال (تذكّر أنَّ كلمة «استبدال» بالإنكليزية هي «Substitute»)، وتُستعمَل الخطوط المائلة <code>/</code> لفصل مختلف الحقول؛ لكن يمكنك استخدام محارف أخرى للفصل بين الحقول إذا ارتأيتَ فائدةً من ذلك.<br>
	على سبيل المثال، إذا كنتَ تحاول تغيير اسم الصفحة في رابط URL، فيمكنك استخدام حرف آخر للفصل بين الحقول (مثلا <code>_</code>) لأنَّ عناوين URL تحتوي على خطوط مائلة <code>/</code> ضمنها. سنفعل ذلك في المثال الآتي الذي نستعمل الأمر <code>echo</code> فيه لتمرير رابط URL عبر أنبوب إلى مجرى الإدخال القياسي للأمر <code>sed</code>:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">echo</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"http://www.example.com/index.html"</span></span><span class="pln"> </span><span class="pun">|</span><span class="pln"> sed </span><span class="hljs-string"><span class="str">'s_com/index_org/home_'</span></span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs avrasm"><span class="hljs-label"><span class="pln">http</span><span class="pun">:</span></span><span class="com">//www</span><span class="hljs-preprocessor"><span class="com">.example</span></span><span class="hljs-preprocessor"><span class="com">.org</span></span><span class="com">/home</span><span class="hljs-preprocessor"><span class="com">.html</span></span></code></pre>

<p>
	لا تنسَ وضع آخر فاصل (المحرف <code>_</code>) أو سيشتكي الأمر <code>sed</code>:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">echo</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"http://www.example.com/index.html"</span></span><span class="pln"> </span><span class="pun">|</span><span class="pln"> sed </span><span class="hljs-string"><span class="str">'s_com/index_org/home'</span></span></code></pre>

<p>
	ستظهر رسالة الخطأ الآتية:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs asciidoc"><span class="pln">sed</span><span class="pun">:</span><span class="pln"> </span><span class="pun">-</span><span class="pln">e expression </span><span class="com">#1, char 22: unterminated </span><span class="hljs-smartquote"><span class="com">`s'</span></span><span class="com"> command</span></code></pre>

<p>
	لنُنشِئ ملفًا للتدرّب على استبدال النصوص (تأكد من كتابة النص على7 أسطُر):
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>echo "this is the song that never ends
yes, it goes on and on, my friend
some people started singing it
not knowing what it was
and they'll continue singing it forever
just because..." &gt; annoying.txt
</code></pre>

<p>
	لنستبدل الآن التعبير <code>forward</code> بالتعبير <code>on</code>:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs vhdl"><span class="pln">sed </span><span class="hljs-attribute"><span class="str">'s</span></span><span class="str">/</span><span class="hljs-keyword"><span class="str">on</span></span><span class="str">/forward/'</span><span class="pln"> annoying</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>this is the sforwardg that never ends
yes, it goes forward and on, my friend
some people started singing it
not knowing what it was
and they'll cforwardtinue singing it forever
just because…
</code></pre>

<p>
	يمكنك أن تلاحظ بعض الإشكاليات في الناتج السابق. أولها هو أننا نستبدل تعابير وليس كلمات، هذا يعني أنَّ التعبير <code>on</code> الموجود ضمن الكلمة <code>song</code> سيصبح <code>forward</code>.
</p>

<p>
	تظهر الإشكالية الثانية في السطر الثاني، حيث لم يُبدّل تعبير <code>on</code> الثاني إلى <code>forward</code>؛ وهذا لأنَّ الأمر <code>s</code> سيُعدِّل أوّل مطابقة في السطر مبدئيًّا، ثم سينتقل إلى السطر الذي يليه؛ ولجعل الأمر <code>sed</code> يُبدِّل كل التعابير الموجودة في السطر بدلًا من أوّل مطابقة، فعلينا تمرير «راية» (flag) اختيارية إلى تعليمة الاستبدال.<br>
	سنوفِّر الراية <code>g</code> إلى تعليمة الاستبدال بوضعها بعد آخر محرف فصل، كما في المثال الآتي:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs vhdl"><span class="pln">sed </span><span class="hljs-attribute"><span class="str">'s</span></span><span class="str">/</span><span class="hljs-keyword"><span class="str">on</span></span><span class="str">/forward/g'</span><span class="pln"> annoying</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>this is the sforwardg that never ends
yes, it goes forward and forward, my friend
some people started singing it
not knowing what it was
and they'll cforwardtinue singing it forever
just because…
</code></pre>

<p>
	أصبحت تعليمة الاستبدال تُغيّر كل مُطابَقة في السطر.<br>
	لكن إذا أردتَ تغيّر ثاني مطابقة للتعبير <code>on</code> في كل سطر، فيمكنك استخدام الرقم <code>2</code> بدلًا من الراية <code>g</code>:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs vhdl"><span class="pln">sed </span><span class="hljs-attribute"><span class="str">'s</span></span><span class="str">/</span><span class="hljs-keyword"><span class="str">on</span></span><span class="str">/forward/</span><span class="hljs-number"><span class="str">2</span></span><span class="str">'</span><span class="pln"> annoying</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>this is the song that never ends
yes, it goes on and forward, my friend
some people started singing it
not knowing what it was
and they'll continue singing it forever
just because…
</code></pre>

<p>
	إذا أردت أن ترى ما هي الأسطر التي استبدِلَت، فيمكنك استخدام الخيار <code>‎-n</code> لإخفاء الأسطر غير المُعدَّلة؛ ثم يمكننا بعد ذلك تمرير الخيار <code>p</code> إلى تعليمة الاستبدال لطباعة الأسطر التي أجريت عليها تلك العملية:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs applescript"><span class="pln">sed </span><span class="pun">-</span><span class="pln">n </span><span class="str">'s/</span><span class="hljs-function_start"><span class="hljs-keyword"><span class="str">on</span></span></span><span class="str">/forward/</span><span class="hljs-number"><span class="str">2</span></span><span class="str">p'</span><span class="pln"> annoying</span><span class="pun">.</span><span class="hljs-type"><span class="pln">text</span></span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>yes, it goes on and forward, my friend
</code></pre>

<p>
	وكما لاحظتَ، يمكننا دمج رايات عدة معًا في نهاية التعليمة.<br>
	إذا أردنا البحث مع إهمال اختلاف حالة الأحرف، فيمكننا استعمال الراية <code>i</code> كما في الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="pln">sed </span><span class="hljs-string"><span class="str">'s/SINGING/saying/i'</span></span><span class="pln"> annoying</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>this is the song that never ends
yes, it goes on and on, my friend
some people started saying it
not knowing what it was
and they'll continue saying it forever
just because…
</code></pre>

<h3 id="إعادة-استخدام-التعابير-التي-تمت-مطابقتها">
	إعادة استخدام التعابير التي تمت مطابقتها
</h3>

<p>
	إذا استخدمنا التعابير النمطية لمطابقة النصوص، فلدينا طرائق مختلفة نستطيع استخدامها للإشارة إلى التعبير الذي تمت مطابقته في النص الذي سنضعه بدلًا من النص الأصلي.<br>
	على سبيل المثال، إذا أردنا أن نطابق من بداية السطر إلى التعبير <code>at</code>، فيمكننا استخدام الأمر الآتي:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="pln">sed </span><span class="hljs-string"><span class="str">'s/^.*at/REPLACED/'</span></span><span class="pln"> annoying</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>REPLACED never ends
yes, it goes on and on, my friend
some people started singing it
REPLACED it was
and they'll continue singing it forever
just because…
</code></pre>

<p>
	لاحظ أنَّ المحرف البديل <code>*</code> أدى إلى المطابقة من بداية السطر <code>^</code> إلى آخر مُطابَقة للتعبير <code>at</code>. ولعدم معرفتك ما هي العبارة التي ستُطابَق في تعبير البحث، فيمكنك استخدام الرمز <code>&amp;</code> في تعبير الاستبدال لتمثيل النص الذي جرت مُطابقته.<br>
	هذا المثال يُظهِر كيف نستطيع وضع قوسين حول النص المُطابَق:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs bash"><span class="pln">sed </span><span class="hljs-string"><span class="str">'s/^.*at/(&amp;)/'</span></span><span class="pln"> annoying</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>(this is the song that) never ends
yes, it goes on and on, my friend
some people started singing it
(not knowing what) it was
and they'll continue singing it forever
just because…
</code></pre>

<p>
	طريقة أخرى أكثر مرونةً للإشارة إلى النص المُطابَق هي استخدام أقواس هلاليّة <code>()</code> لتجميع أقسام من النص المُطابق.<br>
	يمكن الإشارة إلى كل مجموعة من النص المُطابَق والمحاط بالأقواس الهلالية عبر استخدام الأرقام. فمثلًا، نُشير إلى أوّل مجموعة تعابير محاطة بقوسين هلاليين بالتعبير <code>‎\1</code>، والمجموعة الثانية بالتعبير <code>‎\2</code> وهكذا.<br>
	سنُبدِّل في هذا المثال بين أوّل كلمتين في كل سطر (لا تنسَ «تخليص» [escape] الأقواس الهلالية ضمن التعابير النمطية):
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs markdown"><span class="pln">sed </span><span class="str">'s/\([</span><span class="hljs-link_label"><span class="str">a-zA-Z0-9</span></span><span class="str">][</span><span class="hljs-link_reference"><span class="str">a-zA-Z0-9</span></span><span class="str">]</span><span class="hljs-emphasis"><span class="str">*\) \([a-zA-Z0-9][a-zA-Z0-9]*</span></span><span class="str">\)/\2 \1/'</span><span class="pln"> annoying</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>is this the song that never ends
yes, goes it on and on, my friend
people some started singing it
knowing not what it was
they and'll continue singing it forever
because just…
</code></pre>

<p>
	يمكنك ملاحظة أنَّ الناتج ليس مثاليًا؛ فمثلًا، سنتجاهل أوّل كلمة لأنها تحتوي على محرف ليس مذكورًا ضمن مجموعة المحارف التي نريد مطابقتها. وستُعامَل <code>they'll</code> ككلمتين في السطر الخامس.<br>
	لنحسِّن من التعبير النمطي السابق ليصبح أكثر دقةً:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code class="hljs markdown"><span class="pln">sed </span><span class="str">'s/\([</span><span class="hljs-link_label"><span class="str">^ </span></span><span class="str">][</span><span class="hljs-link_reference"><span class="str">^ </span></span><span class="str">]</span><span class="hljs-emphasis"><span class="str">*\) \([^ ][^ ]*</span></span><span class="str">\)/\2 \1/'</span><span class="pln"> annoying</span><span class="pun">.</span><span class="pln">txt</span></code></pre>

<p>
	الناتج:
</p>

<pre class="ipsCode" id="ips_uid_7216_7">
<code>is this the song that never ends
it yes, goes on and on, my friend
people some started singing it
knowing not what it was
they'll and continue singing it forever
because... just
</code></pre>

<p>
	الناتج أفضل بكثير من الناتج السابق، حيث ستُجمَّع علامات الترقيم مع الكلمة التي تتبع لها.<br>
	لاحظ كيف كرَّرنا التعبير داخل القوسين (مرةً دون استخدام المحرف <code>*</code>، ومرةً معه). وهذا لأنَّ المحرف <code>*</code> يؤدي إلى مطابقة مجموعة المحارف التي تسبقه عندما تقع 0 مرة أو أكثر.<br>
	وهذا يعني أنَّ التعبير سيُطابَق حتى لو لم يُعثَر على النمط ضمن النص؛ وللتأكد من وجود التعبير مرةً واحدةً على الأقل، فعلينا مطابقته أولّا دون استخدام <code>*</code>.
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	لقد شرحنا بعض أساسيات استخدام الأمر <code>sed</code>، أتوقع أنَّك عرفتَ الآن سهولة وسرعة تعديل النصوص باستخدام أوامر sed.<br>
	سنشرح في <a href="https://academy.hsoub.com/devops/linux/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85%D8%A7%D8%AA-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%84%D9%84%D9%85%D8%AD%D8%B1%D9%90%D9%91%D8%B1-sed-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r322/" rel="">الدرس القادم</a> ميزاتٍ متقدّمة للمحرِّر sed.
</p>

<p>
	ترجمة –وبتصرّف– للمقال <a href="https://www.digitalocean.com/community/tutorials/the-basics-of-using-the-sed-stream-editor-to-manipulate-text-in-linux" rel="external nofollow">The Basics of Using the Sed Stream Editor to Manipulate Text in Linux</a> لصاحبه Justin Ellingwood
</p>
]]></description><guid isPermaLink="false">318</guid><pubDate>Fri, 26 May 2017 21:06:00 +0000</pubDate></item><item><title>&#x62A;&#x62B;&#x628;&#x64A;&#x62A; &#x648;&#x625;&#x639;&#x62F;&#x627;&#x62F; Ruby on Rails &#x639;&#x644;&#x649; &#x623;&#x648;&#x628;&#x648;&#x646;&#x62A;&#x648; 16.04</title><link>https://academy.hsoub.com/devops/linux/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D9%88%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-ruby-on-rails-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1604-r316/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.b93c0a0af1a56260701eb5d18c977b14.png" /></p>

<p>
	يتناول هذا المقال تثبيت بيئة تطوير Ruby on Rails على الإصدار 16.04 من أوبونتو. في أغلب الأحوال ستُنفَّذ الشفرة البرمجيّة التي تكتبها على خادوم <a href="https://academy.hsoub.com/devops/linux/" rel="">لينكس</a>، وأوبونتو هي إحدى توزيعات لينكس الأسهل استخداما وتوجد الكثير من الموارد عنها على الشبكة.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23283" data-unique="b8u10ulbb" src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.0960307b294c65276570279e0c809c05.png"></p>

<h2 id="تثبيت-ruby">
	تثبيت Ruby
</h2>

<p>
	أول ما يجب علينا فعله هو تثبيت <a href="https://academy.hsoub.com/devops/servers/%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AD%D8%B2%D9%85-%D8%B9%D9%84%D9%89-%D9%86%D8%B3%D8%AE%D8%A9-%D8%A7%D9%84%D8%AE%D9%88%D8%A7%D8%AF%D9%8A%D9%85-%D9%85%D9%86-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-r156/" rel="">الاعتماديات Dependencies</a> التي يحتاجها <a href="https://academy.hsoub.com/programming/ruby/" rel="">Ruby</a> للعمل. نبدأ أولا بتحديث فهرس الحزم ثم تثبيت الاعتماديّات:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs lasso"><span class="pln">sudo apt update
sudo apt install git</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">core</span></span><span class="pln"> curl zlib1g</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> build</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">essential</span></span><span class="pln"> libssl</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> libreadline</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> libyaml</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> libsqlite3</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> sqlite3 libxml2</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> libxslt1</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> libcurl4</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">openssl</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> python</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">software</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">properties</span></span><span class="pln"> libffi</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span><span class="pln"> nodejs</span></code></pre>

<p>
	الخطوة الموالية هي تثبيت Ruby. توجد طرق عدّة للتثبيت، سنستخدم <code>rbenv</code> وهي أداة خفيفة وسريعة لإدارة إصدارات Ruby.
</p>

<p>
	نبدأ بتثبيت <code>rbenv</code> :
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<span class="pln">cd
git clone https</span><span class="pun">:/</span><span class="str">/github.com/</span><span class="pln">rbenv</span><span class="pun">/</span><span class="pln">rbenv</span><span class="pun">.</span><span class="pln">git </span><span class="pun">~/.</span><span class="pln">rbenv
echo </span><span class="str">'export PATH="$HOME/.rbenv/bin:$PATH"'</span><span class="pln"> </span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">bashrc
echo </span><span class="str">'eval "$(rbenv init -)"'</span><span class="pln"> </span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">bashrc
exec $SHELL</span></pre>

<p>
	الأداة <code>rbenv</code> جاهزة الآن. سنثبّت <code>ruby-build</code> وهي إضافة تعمل مع الأداة <code>rbenv</code> وتتيح تثبيت إصدارات عدّة من Ruby في مجلّدات مختلفة على نفس النظام.
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs php"><span class="pln">git </span><span class="hljs-keyword"><span class="pln">clone</span></span><span class="pln"> https</span><span class="pun">:</span><span class="hljs-comment"><span class="com">//github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">echo</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"'</span></span><span class="pln"> </span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="pun">~/.</span><span class="pln">bashrc
</span><span class="kwd">exec</span><span class="pln"> </span><span class="hljs-variable"><span class="pln">$SHELL</span></span></code></pre>

<p>
	ثم نثبّت الإصدار 2.4.0 من Ruby:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs coffeescript"><span class="pln">TMPDIR</span><span class="pun">=~</span><span class="hljs-regexp"><span class="str">/tmp/</span></span><span class="pln">  rbenv install </span><span class="hljs-number"><span class="lit">2.4</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span><span class="pln">
rbenv </span><span class="hljs-built_in"><span class="kwd">global</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">2.4</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">0</span></span></code></pre>

<p>
	يُثبّت الأمر الأول الإصدار المطلوب ضمن مجلّد العمل حيث نُفِّذ الأمر؛ في ما يضبط الأمر الثاني إصدار Ruby المبدئي، أي الإصدار الذي سيُستخدَم عند عدم تحديد إصدار.
</p>

<p>
	للتأكد من تثبيت Ruby والإصدار المثبّت ننفذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs lasso"><span class="pln">ruby </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">v</span></span></code></pre>

<p>
	الذي يُظهر نتيجة تشبه التالي:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs css"><span class="hljs-tag"><span class="pln">ruby</span></span><span class="pln"> </span><span class="lit">2</span><span class="hljs-class"><span class="lit">.4</span></span><span class="hljs-class"><span class="pun">.</span><span class="lit">0p0</span></span><span class="pln"> </span><span class="pun">(</span><span class="lit">2016</span><span class="hljs-tag"><span class="pun">-</span><span class="lit">12</span><span class="pun">-</span><span class="lit">24</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">revision</span></span><span class="pln"> </span><span class="lit">57164</span><span class="pun">)</span><span class="pln"> </span><span class="hljs-attr_selector"><span class="pun">[</span><span class="pln">x86_64</span><span class="pun">-</span><span class="pln">linux</span><span class="pun">]</span></span></code></pre>

<p>
	الخطوة الأخيرة هي تثبيت Bundler الذي يوفّر بيئة تطوير متجانسة لـ Ruby عبر تتبّع الاعتماديات وتثبيت الإصدارات المطلوبة منها بالضبط:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs cmake"><span class="pln">gem </span><span class="hljs-keyword"><span class="pln">install</span></span><span class="pln"> bundler</span></code></pre>

<p>
	وتنفيذ الأمر لأخذ التثبيت الجديد في الحسبان:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs mel"><span class="pln">rbenv </span><span class="hljs-keyword"><span class="pln">rehash</span></span></code></pre>

<h2 id="تثبيت-rails">
	تثبيت Rails
</h2>

<p>
	يتضمّن إطار العمل Rails الكثير من الاعتماديات، لذا سنحتاج لبيئة تنفيذ JavaScript مثل <a href="https://academy.hsoub.com/programming/javascript/nodejs/" rel="">NodeJS</a> التي ستمكّننا من استخدام مكتبات تتيح إمكانيّة جمع وضغط ملفات جافاسكريبت من أجل الحصول على بيئة تطوير أسرع.
</p>

<p>
	نثبّت NodeJS من المستودع الرسمي على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs bash"><span class="pln">curl </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">s</span></span><span class="pln">L https</span><span class="pun">:</span><span class="com">//deb.nodesource.com/setup_4.x | </span><span class="hljs-built_in"><span class="com">sudo</span></span><span class="com"> -E bash -</span><span class="pln">
</span><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> apt install </span><span class="pun">-</span><span class="pln">y nodejs</span></code></pre>

<p>
	ثم نثبّت Rails:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs cmake"><span class="pln">gem </span><span class="hljs-keyword"><span class="pln">install</span></span><span class="pln"> rails </span><span class="pun">-</span><span class="pln">v </span><span class="hljs-number"><span class="lit">5.0</span></span><span class="pun">.</span><span class="hljs-number"><span class="lit">1</span></span></code></pre>

<p>
	ثم ننفذ الأمر التالي ليمكننا استخدام Rails:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs mel"><span class="pln">rbenv </span><span class="hljs-keyword"><span class="pln">rehash</span></span></code></pre>

<p>
	Rails مثبّت الآن، يمكننا التأكّد من ذلك بتنفيذ الأمر التالي الذي يُظهر رقم الإصدار المثبت:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs lasso"><span class="pln">rails </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">v</span></span></code></pre>

<h2 id="إعداد-قاعدة-بيانات-mysql">
	إعداد قاعدة بيانات MySQL
</h2>

<p>
	يأتي Rails مبدئيا بقاعدة بيانات sqlite3؛ إلا أن هذا النوع من قواعد البيانات <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%82%D8%A7%D8%B1%D9%86%D8%A9-%D8%A8%D9%8A%D9%86-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-sqlite-%D9%85%D8%B9-mysql-%D9%85%D8%B9-postgresql-r72/" rel="">لا يناسب تطبيقات كثيرة</a>. يمكن في هذه الحالة إعداد Rails للعمل مع قاعدة بيانات MySQL (أو PostgreSQL).
</p>

<p>
	نثبّت خادوم وعميل MySQL من المستودعات الرسمية لأوبونتو:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs lasso"><span class="pln">sudo apt install mysql</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">server</span></span><span class="pln"> mysql</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">client</span></span><span class="pln"> libmysqlclient</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dev</span></span></code></pre>

<p>
	سيُطلَب منك خلال التثبيت إنشاءُ كلمة سر خاصة بالحساب الإداري <code>root</code> (انتبِه إلى أنّه حساب خاص بنظام MySQL لإدارة قواعد البيانات، وليس لنظام التشغيل أوبونتو).
</p>

<p>
	تتضمّن الحزمة <code>libmysqlclient-dev</code> الملفات الضرورية لتثبيت الاعتماديّات التي يحتاجها Rails للاتصال بقاعدة بيانات MySQL.
</p>

<p>
	ننفّذ بعد تثبيت MySQL الأمريْن التاليّيْن لتحضير قاعدة البيانات لبيئة الإنتاج (يمكنك تجاوز هذه الخطوة إن كنت تثبّت Rails على حاسوب شخصي):
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> mysql_install_db
</span><span class="hljs-built_in"><span class="pln">sudo</span></span><span class="pln"> mysql_secure_installation</span></code></pre>

<p>
	سيُطلب منك النّظام إدخال كلمة سرّ الحساب الجذر في MySQL؛ ثمّ يسألك ما إذا كنتَ تُريد تغييرها. أدخل حرف n (دلالةً على “no” أي “لا”) إن لم تكن ترغبُ في ذلك. بالنسبة لبقية الأسئلة يمكنك قبول القيم المبدئية بالنقر على زرّ <code>Enter</code>.
</p>

<h3 id="أول-تطبيق-rails">
	أول تطبيق Rails
</h3>

<p>
	حان الوقت الآن لتشغيل أول تطبيق Ruby on Rails.
</p>

<p>
	ننشئ تطبيقا باسم <code>myapp</code> يستخدم قاعدة البيانات MySQL:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs lasso"><span class="pln">rails </span><span class="hljs-literal"><span class="kwd">new</span></span><span class="pln"> myapp </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">d</span></span><span class="pln"> mysql</span></code></pre>

<p>
	انتظر اكتمال إنشاء التطبيق الذي قد يستغرق وقتا، ثم انتقل إلى مجلد التطبيق:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">cd</span></span><span class="pln"> myapp</span></code></pre>

<p>
	عدّل الملف <code>config/database.yml</code> بإضافة كلمة سر الحساب الإداري لقاعدة البيانات (أعددناها أثناء تثبيت MySQL، يمكنك تركها فارغة إن لم تكن أعددتَ كلمة سر لـ MySQL):
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs http"><span class="hljs-attribute"><span class="kwd">default</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="pun">&amp;</span><span class="kwd">default</span></span><span class="pln">
  </span><span class="hljs-attribute"><span class="pln">adapter</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="pln">mysql2</span></span><span class="pln">
  </span><span class="hljs-attribute"><span class="pln">encoding</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="pln">utf8</span></span><span class="pln">
  </span><span class="hljs-attribute"><span class="pln">pool</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="lit">5</span></span><span class="pln">
  </span><span class="hljs-attribute"><span class="pln">username</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="pln">root</span></span><span class="pln">
  </span><span class="hljs-attribute"><span class="pln">password</span></span><span class="pun">:</span><span class="pln"> 
  </span><span class="hljs-attribute"><span class="pln">socket</span></span><span class="pun">:</span><span class="pln"> </span><span class="hljs-string"><span class="str">/var/</span><span class="pln">run</span><span class="pun">/</span><span class="pln">mysqld</span><span class="pun">/</span><span class="pln">mysqld</span><span class="pun">.</span><span class="pln">sock</span></span></code></pre>

<p>
	اكتب كلمة السر أمام التعليمة <code>password</code> ضمن المقطع السابق الموجود أعلى الملف بعد التعليقات الأولى (تبدأ التعليقات بالعلامة <code>#</code>)؛ ثم نفّذ الأمر التالي لإنشاء قاعدة البيانات التي سيعمل عليها التطبيق:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs css"><span class="hljs-tag"><span class="pln">rake</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">db</span></span><span class="hljs-pseudo"><span class="pun">:</span><span class="pln">create</span></span></code></pre>

<p>
	النتيجة:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs bash"><span class="typ">Created</span><span class="pln"> database </span><span class="hljs-string"><span class="str">'myapp_development'</span></span><span class="pln">
</span><span class="typ">Created</span><span class="pln"> database </span><span class="hljs-string"><span class="str">'myapp_test'</span></span></code></pre>

<p>
	إن واجهك خطأ <code>Access denied for user 'root'@'localhost' (using password: NO)</code> فهذا يعني أنك لم تكتب كلمة السر بطريقة صحيحة.
</p>

<p>
	نشغل خادوم التطوير:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs axapta"><span class="pln">rails </span><span class="hljs-keyword"><span class="pln">server</span></span></code></pre>

<p>
	يمكنك بعد تشغيل خادوم التطوير إدخال العنوان <code><a href="http://localhost:3000/" ipsnoembed="false" rel="external nofollow">http://localhost:3000/</a></code> في المتصفح لمعاينة صفحة التطبيق المبدئي في Rails.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="23282" href="https://academy.hsoub.com/uploads/monthly_2017_05/01_rails_server.png.98ab5cdbbfb97c2836f1d8e1b60705eb.png" rel=""><img alt="01_rails_server.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23282" data-unique="xjlacatf0" src="https://academy.hsoub.com/uploads/monthly_2017_05/01_rails_server.thumb.png.79a186281e9de185b50a102e48b487f2.png"></a>
</p>

<h2 id="إعداد-git">
	إعداد Git
</h2>

<p>
	هذه الخطوة اختيارية ولكنه تفيدك إن كنت تخطّط لاستعمال <a href="https://academy.hsoub.com/programming/workflow/git/" rel="">Git</a> لإدارة إصدارات المشروع وربطه بحسابك على Github.
</p>

<p>
	أبدل <code>YOUR NAME</code> و<code>YOUR@EMAIL.com</code> في الأوامر أدناه على التوالي باسمك والبريد الذي استخدمته للتسجيل على Github.
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs lasso"><span class="pln">git config </span><span class="hljs-subst"><span class="pun">--</span></span><span class="hljs-built_in"><span class="kwd">global</span></span><span class="pln"> color</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">ui </span><span class="hljs-literal"><span class="kwd">true</span></span><span class="pln">
git config </span><span class="hljs-subst"><span class="pun">--</span></span><span class="hljs-built_in"><span class="kwd">global</span></span><span class="pln"> user</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">name </span><span class="hljs-string"><span class="str">"YOUR NAME"</span></span><span class="pln">
git config </span><span class="hljs-subst"><span class="pun">--</span></span><span class="hljs-built_in"><span class="kwd">global</span></span><span class="pln"> user</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">email </span><span class="hljs-string"><span class="str">"YOUR@EMAIL.com"</span></span><span class="pln">
<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">keygen</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">t</span></span><span class="pln"> rsa </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">b</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4096</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">C</span></span><span class="pln"> </span><span class="hljs-string"><span class="str">"YOUR@EMAIL.com"</span></span></code></pre>

<p>
	يُولّد الأمر الأخير في الأوامر أعلاه زوج مفاتيح <a href="https://academy.hsoub.com/devops/security/ssh/" rel=""><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr></a> سنستخدمها في ما بعد للاتصال بحسابنا على Github. يضع الأمر <code><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>-keygen</code> مبدئيا زوج المفاتيح على المسار <code><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>./~</code>. نأخذ المفتاح العمومي الذي يوجد بملف المفتاح ذي الامتداد <code>pub</code>، ويُسمّى مبدئيا <code>id_rsa.pub</code> وننسخه ضمن مفاتيح <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> على حسابنا في Github <a href="https://github.com/settings/ssh" rel="external nofollow">الموجودة هنا</a>. انقر على الزّر New <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> Key، أعط للمفتاح اسما تختاره ثم ألصق في الحقل الثاني محتوى الملف <code><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>/id_rsa.pub/~</code> الذي يمكن الحصول عليه بالأمر التالي، ثم انقر على زرّ Add <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr> Key لاعتماد المفتاح:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs avrasm"><span class="pln">cat </span><span class="pun">~</span><span class="str">/</span><span class="hljs-preprocessor"><span class="str">.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr></span></span><span class="str">/</span><span class="pln">id_rsa</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">pub</span></span></code></pre>

<p>
	يمكنك التأكد من نجاح العملية بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs ruby"><span class="pln"><abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> </span><span class="pun">-</span><span class="hljs-constant"><span class="pln">T</span></span><span class="pln"> git</span><span class="hljs-variable"><span class="pln">@github</span></span><span class="pun">.</span><span class="pln">com</span></code></pre>

<p>
	يجب أن تظهر لك رسالة تشبه التالي (يُذكَر فيها اسم حسابك على Github):
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_8167_7" style="">
<code class="hljs vhdl"><span class="typ">Hi</span><span class="pln"> </span><span class="typ">Zeine77</span><span class="pun">!</span><span class="pln"> </span><span class="typ">You</span><span class="hljs-attribute"><span class="str">'ve</span></span><span class="str"> successfully authenticated, but GitHub does </span><span class="hljs-keyword"><span class="str">not</span></span><span class="str"> provide shell </span><span class="hljs-keyword"><span class="str">access</span></span><span class="str">.</span></code></pre>

<p>
	ترجمة - بتصرّف - للمقال <a href="https://gorails.com/setup/ubuntu/16.04" rel="external nofollow">Setup Ruby On Rails on Ubuntu 16.04 Xenial Xerus</a>.
</p>
]]></description><guid isPermaLink="false">316</guid><pubDate>Fri, 19 May 2017 13:03:07 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x62B;&#x628;&#x651;&#x62A; Composer &#x648;&#x62A;&#x633;&#x62A;&#x62E;&#x62F;&#x645;&#x647; &#x639;&#x644;&#x649; Ubuntu 16.04</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%AB%D8%A8%D9%91%D8%AA-composer-%D9%88%D8%AA%D8%B3%D8%AA%D8%AE%D8%AF%D9%85%D9%87-%D8%B9%D9%84%D9%89-ubuntu-1604-r315/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.3c2a2277c0910994fabef43486f671f8.png" /></p>

<h2 id="مقدمة">
	مقدّمة
</h2>

<p>
	يعدّ Composer أحد أكثر الأدوات شيوعا بين مطّوري <a href="https://academy.hsoub.com/programming/php/" rel="">PHP</a>، فهو مستخدم لإدارة الاعتمادات Dependency management إذ يُسهّل كثيرا من تثبيت وتحديث المكتبات البرمجيّة التي يحتاجها المشروع قيد التطوير. يتحقّق Composer من المكتبات التي يعتمد عليها المشروع ويثبّت الإصدار المناسب منها لمتطلّبات المشروع.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23202" data-unique="hb26pg6eu" src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.2ca73e95bcf1050e0b99c4e9d56c5790.png"></p>

<p>
	يشرح هذا المقال كيفية تثبيت Composer واستخدامه على توزيعة أوبونتو 16.04. سنفترض في هذا المقال أن لديك خادوما يعمل بالإصدار المذكور، إضافة إلى <a href="https://academy.hsoub.com/devops/servers/%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A7%D9%84%D8%A7%D8%A8%D8%AA%D8%AF%D8%A7%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r4/#%D8%A7%D9%85%D8%AA%D9%8A%D8%A7%D8%B2%D8%A7%D8%AA-%D8%A7%D9%84%D8%AC%D8%B0%D8%B1" rel="">مستخدم أعلى Super user</a>.
</p>

<h2 id="تثبيت-الاعتمادات">
	تثبيت الاعتمادات
</h2>

<p>
	ينبغي أن نتأكّد أولا، قبل تنزيل Composer، أن <a href="https://academy.hsoub.com/devops/linux/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AD%D8%B2%D9%85-%D9%81%D9%8A-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-%D9%88%D8%AF%D8%A8%D9%8A%D8%A7%D9%86-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%84-r248/" rel="">حزم البرامج</a> التي يحتاجها موجودة على نظام التشغيل لدينا.
</p>

<p>
	نبدأ بتحديث فهرس الحزم:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
sudo apt-get update
</pre>

<p>
	ثم نثبّت الحزم المطلوبة:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs lasso"><span class="pln">sudo apt install curl php</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">cli</span></span><span class="pln"> php</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">mbstring</span></span><span class="pln"> git unzip</span></code></pre>

<p>
	نحتاج <code>curl</code> لتنزيل Composer و<code>php-cli</code> لتثبيته وتشغيله. ستكون الحزمة <code>php-mbstring</code> مطلوبة لاستخدام دوال تحتاجها مكتبة سنستخدمها لاحقا. بالنسبة لـ <a href="https://academy.hsoub.com/programming/workflow/git/" rel=""><code>git</code></a> فيحتاجه Composer لتنزيل اعتمادات المشاريع؛ أما <code>unzip</code> فيُستخدَم لاستخراج ملفات Zip.
</p>

<h2 id="تنزيل-composer-وتثبيته">
	تنزيل Composer وتثبيته
</h2>

<p>
	يوفّر Composer برنامج تثبيت مكتوبا بـ PHP. تأكّد من أنك موجود في المجلّد الشخصي للمستخدم ثم احصُل على ملف التثبيت بالأمر <code>curl</code> على النحو التالي:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">cd</span></span><span class="pln"> </span><span class="pun">~</span><span class="pln">
curl </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">s</span></span><span class="pln">S https</span><span class="pun">:</span><span class="com">//getcomposer.org/installer -o composer-setup.php</span></code></pre>

<p>
	ينزّل الأمر السابق ملف التثبيت ويحفظه في المجلد الشخصي باسم <code>composer-setup.php</code>. سنتأكّد من أن الملف الذي نزّلناه يوافق <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%A7%D9%84%D9%81%D8%B1%D9%82-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AA%D8%B1%D9%85%D9%8A%D8%B2-encoding%D8%8C-%D8%A7%D9%84%D8%AA%D8%B9%D9%85%D9%8A%D8%A9-encryption%D8%8C-%D8%A7%D9%84%D8%AA%D8%AC%D8%B2%D8%A6%D8%A9-hashing-%D9%88%D8%A7%D9%84%D8%AA%D8%B4%D9%88%D9%8A%D8%B4-obfuscation%D8%9F-r308/#%D8%A7%D9%84%D8%AA%D8%AC%D8%B2%D8%A6%D8%A9" rel="">التجزئة Hash</a> الخاصة بالملف على موقع Composer للتأكد من سلامته.
</p>

<p>
	افتح <a href="https://composer.github.io/pubkeys.html" rel="external nofollow">الصفحة التاليّة</a> وانسخ سلسلة المحارف تحت العنوان Installer Signature (SHA-384) المكوّنة من 96 محرفا مكان <code>SHA-384</code> في السكربت أدناه، بين الظفرين:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">

<code>php -r "if (hash_file('SHA384', 'composer-setup.php') === '**SHA-384**') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
</code></pre>

<p>
	ينبغي أن يطبع السكربت الجملة التالية:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs "><span class="typ">Installer</span><span class="pln"> verified</span></code></pre>

<p>
	نثبّت Composer على النحو التالي ليكون متاحا على أي مجلّد في النظام”
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs lasso"><span class="pln">sudo php composer</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">setup</span></span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">php </span><span class="hljs-subst"><span class="pun">--</span></span><span class="pln">install</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">dir</span></span><span class="hljs-subst"><span class="pun">=</span></span><span class="str">/usr/</span><span class="hljs-built_in"><span class="kwd">local</span></span><span class="pun">/</span><span class="pln">bin </span><span class="hljs-subst"><span class="pun">--</span></span><span class="pln">filename</span><span class="hljs-subst"><span class="pun">=</span></span><span class="pln">composer</span></code></pre>

<p>
	ينزّل اﻷمر أعلاه Composer ويجعل الأمر <code>composer</code> متاحا على كامل النظام:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs r"><span class="typ">All</span><span class="pln"> settings correct </span><span class="hljs-keyword"><span class="kwd">for</span></span><span class="pln"> </span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Composer</span><span class="pln">
</span><span class="typ">Downloading</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1.4</span></span><span class="hljs-number"><span class="pun">.</span><span class="lit">1</span></span><span class="hljs-keyword"><span class="lit">.</span><span class="pun">..</span></span><span class="pln">

</span><span class="typ">Composer</span><span class="pln"> successfully installed to</span><span class="pun">:</span><span class="pln"> </span><span class="str">/usr/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">composer
</span><span class="typ">Use</span><span class="pln"> it</span><span class="pun">:</span><span class="pln"> php </span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">composer</span></code></pre>

<p>
	للتحقّق من التثبيت نفّذ الأمر <code>composer</code> بدون تمرير معطيات. تظهر النتيجة التالية:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs haml"><span class="pln">   ______
</span><span class="hljs-comment"><span class="pln">  </span><span class="pun">/</span><span class="pln"> ____</span><span class="pun">/</span><span class="pln">___  ____ ___  ____  ____  ________  _____</span></span><span class="pln">
</span><span class="hljs-comment"><span class="pln"> </span><span class="str">/ /</span><span class="pln">   </span><span class="pun">/</span><span class="pln"> __ \/ __ </span><span class="str">`__ \/ __ \/ __ \/ ___/ _ \/ ___/</span></span><span class="str">
</span><span class="hljs-comment"><span class="str">/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /</span></span><span class="str">
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
</span><span class="hljs-comment"><span class="str">                    /_/</span></span><span class="str">
Composer version 1.4.1 2017-03-10 09:29:45

Usage:
  command [options] [arguments]

Options:
  -</span><span class="ruby"><span class="str">h, --help                     </span><span class="hljs-constant"><span class="str">Display</span></span><span class="str"> this help message
</span></span><span class="str">  -</span><span class="ruby"><span class="str">q, --quiet                    </span><span class="hljs-constant"><span class="str">Do</span></span><span class="str"> </span><span class="hljs-keyword"><span class="str">not</span></span><span class="str"> output any message
</span></span><span class="str">  -</span><span class="ruby"><span class="hljs-constant"><span class="str">V</span></span><span class="str">, --version                  </span><span class="hljs-constant"><span class="str">Display</span></span><span class="str"> this application version
</span></span><span class="str">      -</span><span class="ruby"><span class="str">-ansi                     </span><span class="hljs-constant"><span class="str">Force</span></span><span class="str"> </span><span class="hljs-constant"><span class="str">ANSI</span></span><span class="str"> output
</span></span><span class="str">      -</span><span class="ruby"><span class="str">-no-ansi                  </span><span class="hljs-constant"><span class="str">Disable</span></span><span class="str"> </span><span class="hljs-constant"><span class="str">ANSI</span></span><span class="str"> output
</span></span><span class="str">  -</span><span class="ruby"><span class="str">n, --no-interaction           </span><span class="hljs-constant"><span class="str">Do</span></span><span class="str"> </span><span class="hljs-keyword"><span class="str">not</span></span><span class="str"> ask any interactive question
</span></span><span class="str">      -</span><span class="ruby"><span class="str">-profile                  </span><span class="hljs-constant"><span class="str">Display</span></span><span class="str"> timing </span><span class="hljs-keyword"><span class="str">and</span></span><span class="str"> memory usage information
</span></span><span class="str">      -</span><span class="ruby"><span class="str">-no-plugins               </span><span class="hljs-constant"><span class="str">Whether</span></span><span class="str"> to disable plugins.
</span></span><span class="str">  -</span><span class="ruby"><span class="str">d, --working-dir=</span><span class="hljs-constant"><span class="str">WORKING</span></span><span class="str">-</span><span class="hljs-constant"><span class="str">DIR</span></span><span class="str">  </span><span class="hljs-constant"><span class="str">If</span></span><span class="str"> specified, use the given directory as working directory.
</span></span><span class="str">  -</span><span class="ruby"><span class="str">v|vv|vvv, --verbose           </span><span class="hljs-constant"><span class="str">Increase</span></span><span class="str"> the verbosity of </span><span class="hljs-symbol"><span class="str">messages:</span></span><span class="str"> </span><span class="hljs-number"><span class="str">1</span></span><span class="str"> </span><span class="hljs-keyword"><span class="str">for</span></span><span class="str"> normal output, </span><span class="hljs-number"><span class="str">2</span></span><span class="str"> </span><span class="hljs-keyword"><span class="str">for</span></span><span class="str"> more verbose output </span><span class="hljs-keyword"><span class="str">and</span></span><span class="str"> </span><span class="hljs-number"><span class="str">3</span></span><span class="str"> </span><span class="hljs-keyword"><span class="str">for</span></span><span class="str"> debug
</span></span><span class="str">
Available commands:
(...)</span></code></pre>

<p>
	يعني هذا أن Composer ثُبِّت بنجاح على نظامك.
</p>

<p>
	يمكنك كذلك أن تبقي على ملفات Composer تنفيذية خاصّة بكل مشروع بدلا من أن يكون الأمر <code>composer</code> متاحا على كامل النظام. تفيد هذه الطريقة أيضا مفيدة إذا كان المستخدم لا يملك صلاحيات تثبيت الأداة على كامل النظام. في هذه الحالة يكون التثبيت بتنفيذ الأمر التالي بعد تنزيل ملف التثبيت والتحقق منه:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs avrasm"><span class="pln">php composer</span><span class="pun">-</span><span class="pln">setup</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">php</span></span></code></pre>

<p>
	سيولّد الأمر أعلاه ملف <code>composer.phar</code> في المجلد الذي نُفِّذ فيه الأمر. لتشغيل Composer بعد التثبيت بهذه الطريقة نفّذ الأمر من داخل مجلّد التثبيت:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs avrasm"><span class="pun">./</span><span class="pln">composer</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">phar</span></span></code></pre>

<h2 id="توليد-ملف-composerjson">
	توليد ملف composer.json
</h2>

<p>
	ثبّتنا Composer ونحن الآن جاهزون لاستخدامه. أولّ ما يجب علينا فعله لاستغلال إمكانيّات Composer هو إنشاء ملف <code>composer.json</code>. دور ملف <code>composer.json</code> هو إخبار Composer بالمكتبات البرمجيّة التي يحتاجها المشروع الذي نعمل عليه (الاعتمادات)، مع تحديد الإصدارات المطلوبة. من المهمّ جدا تحديد الإصدارات بحيث تتناسق مع مشروعك وتتجنّب تثبيت إصدارات غير مستقرّة قد تؤثّر سلبا على ما تعمل عليه.
</p>

<p>
	ليس ضروريّا إنشاءُ ملف <code>composer.json</code> يدويّا، بل إن ذلك يجعل احتمال الأخطاء المطبعيّة في الصياغة أكبر. يولّد Composer ملف <code>composer.json</code> تلقائيا عند إضافة متطلّبات جديدة إلى المشروع بالأمر <code>composer require</code>.
</p>

<p>
	يمرّ استخدامُ Composer لتثبيت اعتماد جديد عادة على الخطوات التاليّة:
</p>

<ul>
<li>
		تحديد نوع المكتبة البرمجيّة التي يحتاجها مشروعك.
	</li>
	<li>
		البحث عن مكتبة مناسبة على الموقع <a href="https://packagist.org/" rel="external nofollow">Packagist.org</a>، وهو المستودع الرسمي لحزم Composer.
	</li>
	<li>
		اختيار المكتبة البرمجية التي تريد استخدامها في مشروعك.
	</li>
	<li>
		استعمال الأمر <code>composer require</code> لإضافة المكتبة إلى الملف <code>composer.json</code>.
	</li>
	<li>
		تثبيت الحزمة.
	</li>
</ul>
<p>
	سنعرض في ما يلي تطبيقا تجريبيا نطبّق من خلاله هذه الخطوات. سيكون الهدف من التطبيق تحويل جملة معيّنة إلى سلسلة محارف تصلح لتكون جزءا من رابط URL، ضمن ما يُعرَف بـ Slug. تُستخدَم هذه الطريقة كثيرا لجعل عنوان صفحة رابطا لها +(تنطبق هذه الملاحظة على المقال الذي تقرأه الآن).
</p>

<p>
	نبدأ بإنشاء مجلّد للمشروع نسمّيه <code>slugify</code> ضمن المجلّد الشخصي للمستخدم:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs bash"><span class="hljs-built_in"><span class="pln">cd</span></span><span class="pln"> </span><span class="pun">~</span><span class="pln">
mkdir slugify
</span><span class="hljs-built_in"><span class="pln">cd</span></span><span class="pln"> slugify</span></code></pre>

<h3 id="البحث-عن-حزم-مكتبات-على-packagist">
	البحث عن حزم مكتبات على Packagist
</h3>

<p>
	حان الآن موعد البحث عن مكتبة على <a href="https://packagist.org/" rel="external nofollow">Packagist.org</a> لاستخدامها في توليد Slug في مشروعنا. إن بحثت على الموقع عن الكلمة المفتاحية slug فستجد نتائج تشبه التالي.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="23201" href="https://academy.hsoub.com/uploads/monthly_2017_05/01_packagist_slug.png.367772e3137d267192ec88cc4737b406.png" rel=""><img alt="01_packagist_slug.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23201" data-unique="olmx87r5t" src="https://academy.hsoub.com/uploads/monthly_2017_05/01_packagist_slug.thumb.png.1aec823aa7f03830132fe844a9c9403e.png"></a>
</p>

<p>
	يظهر عددان في الجانب الأيمن لكلّ حزمة في قائمة نتائج البحث. يدلّ العدد الأعلى على مرات تثبيت الحزمة، أما العدد الأسفل فيعني عدد المرات التي حصلت فيها الحزمة على نجمة على Github. يمكنك إعادة ترتيب الحزم حسب هذين العدديْن. عموما، كل ما كانت التثبيتات والنجوم أكثر كلّ ما دلّ ذلك على ثبات الحزمة؛ إلا أن من المهمّ قراءة وصف الحزمة حتى تتأكد من موافقتها لما تريد.
</p>

<p>
	نحتاج لمكتبة بسيطة تحوّل الجمل إلى سلسلة محارف لاستخدامها في الروابط. يبدو من أوصاف الحزم في نتائج البحث أن الحزمة <code>cocur/slugify</code> (لا تظهر في لقطة الشاشة أعلاه) مناسبة لنا، كما أن عدد مرات تثبيتها ونجومها مقبول، لذا سنختارها.
</p>

<p>
	ربما لاحظت أن أسماء الحزم على Packagist تتضمّن خانتين مفصولتين بشريط مائل. تحيل الخانة الأولى إلى الشركة أو الشخص المطوِّر للحزمة Vendor (وهو <code>cocur</code> في الحزمة التي اخترناها)، أما الخانة الثانيّة فهي اسم الحزمة (<code>slugify</code>). تشكّل الخانتان فضاء أسماء خاصًّا بالحزمة، وهو ما سنمرّره للأمر <code>composer require</code> عند طلب إضافة الحزمة إلى اعتمادات مشروعنا.
</p>

<h3 id="جعل-حزمة-من-متطلبات-المشروع">
	جعل حزمة من متطلبات المشروع
</h3>

<p>
	نعرف الآن ماهي الحزمة البرمجيّة التي نريد الاعتماد عليها في مشروعنا. الخطوة المواليّة هي إخبار Composer أن هذه الحزمة مطلوبة لمشروعنا؛ لذا سننفّذ الأمر <code>composer require</code> ونمرّر له فضاء الأسماء الخاصّ بالحزمة:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs ruby"><span class="pln">composer </span><span class="hljs-keyword"><span class="kwd">require</span></span><span class="pln"> cocur</span><span class="pun">/</span><span class="pln">slugify</span></code></pre>

<p>
	تظهر مُخرجات الأمر التالية:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs livecodeserver"><span class="typ">Using</span><span class="pln"> </span><span class="hljs-built_in"><span class="pln">version</span></span><span class="pln"> </span><span class="pun">^</span><span class="hljs-number"><span class="lit">2.5</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">for</span></span><span class="pln"> cocur</span><span class="pun">/</span><span class="pln">slugify
</span><span class="pun">./</span><span class="pln">composer</span><span class="pun">.</span><span class="pln">json has been created
</span><span class="typ">Loading</span><span class="pln"> composer repositories </span><span class="hljs-operator"><span class="kwd">with</span></span><span class="pln"> </span><span class="kwd">package</span><span class="pln"> information
</span><span class="typ">Updating</span><span class="pln"> dependencies </span><span class="pun">(</span><span class="pln">including </span><span class="hljs-built_in"><span class="kwd">require</span></span><span class="pun">-</span><span class="pln">dev</span><span class="pun">)</span><span class="pln">
</span><span class="typ">Package</span><span class="pln"> operations</span><span class="pun">:</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> install</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> updates</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-number"><span class="lit">0</span></span><span class="pln"> removals
  </span><span class="pun">-</span><span class="pln"> </span><span class="typ">Installing</span><span class="pln"> cocur</span><span class="pun">/</span><span class="pln">slugify </span><span class="pun">(</span><span class="pln">v2</span><span class="hljs-number"><span class="pun">.</span><span class="lit">5</span></span><span class="pun">):</span><span class="pln">   </span><span class="typ">Downloading</span><span class="pln"> </span><span class="pun">(</span><span class="hljs-number"><span class="lit">100</span></span><span class="pun">%)</span><span class="pln">      

</span><span class="typ">Writing</span><span class="pln"> </span><span class="kwd">lock</span><span class="pln"> </span><span class="hljs-built_in"><span class="pln">file</span></span><span class="pln">
</span><span class="typ">Generating</span><span class="pln"> autoload </span><span class="hljs-built_in"><span class="pln">files</span></span></code></pre>

<p>
	يقرّر Composer تلقائيا، كما يظهر في المخرجات أعلاه، أي إصدار من الحزمة البرمجية سيُثبِّت.<br>
	إن تحقّقت الآن من مجلّد المشروع فستجد ملفّيْن جديديْن هما <code>composer.json</code> و<code>composer.lock</code> ومجلدًّا فرعيّا جديدا باسم <code>vendor</code>:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs bash"><span class="pln">ls </span><span class="hljs-operator"><span class="pun">-</span><span class="pln">l</span></span></code></pre>

<p>
	النتيجة:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs lasso"><span class="pln">total </span><span class="hljs-number"><span class="lit">28</span></span><span class="pln">
</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">rw</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">rw</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">r</span></span><span class="hljs-subst"><span class="pun">--</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> zeine77 zeine77   </span><span class="hljs-number"><span class="lit">59</span></span><span class="pln"> </span><span class="typ">Apr</span><span class="pln"> </span><span class="hljs-number"><span class="lit">10</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">15</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">15</span></span><span class="pln"> composer</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="pln">json
</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">rw</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">rw</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">r</span></span><span class="hljs-subst"><span class="pun">--</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pln"> zeine77 zeine77 </span><span class="hljs-number"><span class="lit">2901</span></span><span class="pln"> </span><span class="typ">Apr</span><span class="pln"> </span><span class="hljs-number"><span class="lit">10</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">15</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">15</span></span><span class="pln"> composer</span><span class="hljs-built_in"><span class="pun">.</span></span><span class="kwd">lock</span><span class="pln">
drwxrwxr</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">x</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">4</span></span><span class="pln"> zeine77 zeine77 </span><span class="hljs-number"><span class="lit">4096</span></span><span class="pln"> </span><span class="typ">Apr</span><span class="pln"> </span><span class="hljs-number"><span class="lit">10</span></span><span class="pln"> </span><span class="hljs-number"><span class="lit">15</span></span><span class="pun">:</span><span class="hljs-number"><span class="lit">15</span></span><span class="pln"> vendor</span></code></pre>

<p>
	يُستخدَم الملفّ <code>composer.lock</code> لحفظ معلومات عن إصدارات المكتبات البرمجيّة المثبّتة، والتأكّد من استخدام نفس الإصدارات عندما <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%B3%D9%8A%D8%B1-%D8%B9%D9%85%D9%84-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%AD%D9%83%D9%85-%D9%81%D9%8A-%D8%A7%D9%84%D9%86%D8%B3%D8%AE-git-r267/#%D9%86%D8%B3%D8%AE-%D9%85-%D8%B3%D8%AA%D9%88%D8%AF%D8%B9-%D8%B1%D8%A7%D9%87%D9%86:5bc8635476404749f76287ef866562d6" rel="">ينسخ مطوّر</a> آخر مشروعك للعمل عليه.<br>
	تُخزَّن في المجلّد <code>vendor</code> ملفّات المكتبات البرمجيّة. يجب ألّا يودَع Commit المجلّد <code>vendor</code> في <a href="https://academy.hsoub.com/programming/workflow/git/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%86%D8%B3%D8%AE-vcs-r248/" rel="">نظام إدارة النسخ</a>، بل يُكتفى ب<a href="https://academy.hsoub.com/programming/workflow/git/%D9%85%D8%A8%D8%A7%D8%AF%D8%A6-git-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-r256/" rel="">إيداع</a> الملفيْن <code>composer.lock</code> و<code>composer.json</code>. عند تثبيت مشروع يحتوي على ملفّ <code>composer.json</code> ستحتاج إلى تنفيذ الأمر <code>composer install</code> من أجل تنزيل اعتمادات المشروع.
</p>

<h3 id="فهم-القيود-على-إصدارات-الاعتمادات">
	فهم القيود على إصدارات الاعتمادات
</h3>

<p>
	فلنطبع محتوى الملف <code>composer.json</code>:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs avrasm"><span class="pln">cat composer</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">json</span></span></code></pre>

<p>
	تظهر النتيجة التاليّة (قد يختلف الإصدار قليلا لديك):
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs json"><span class="pun">{</span><span class="pln">
    </span><span class="str">"</span><span class="hljs-attribute"><span class="str">require</span></span><span class="str">"</span><span class="pun">:</span><span class="pln"> </span><span class="hljs-value"><span class="pun">{</span><span class="pln">
        </span><span class="str">"</span><span class="hljs-attribute"><span class="str">cocur/slugify</span></span><span class="str">"</span><span class="pun">:</span><span class="pln"> </span><span class="hljs-value"><span class="hljs-string"><span class="str">"^2.5"</span></span><span class="pln">
    </span></span><span class="pun">}</span><span class="pln">
</span></span><span class="pun">}</span></code></pre>

<p>
	ربّما لاحظت المحرف الخاصّ <code>^</code> أمام رقم الإصدار في الملفّ <code>composer.json</code>. يدعم Composer صيغًا وشروطا مختلفة لتحديد الإصدارات المطلوبة من الحزم والمكتبات البرمجيّة، من أجل الحفاظ على ثبات المشروع مع السماح بمرونة أكبر حسب الحاجة. يُنصَح بالعامل <code>^</code>، المستخدَم عند توليد الملف <code>composer.json</code> تلقائيًّا، للحصول على أعلى قدر من الاستقرار. يعني استخدام <code>^</code> أن الإصدار <code>2.5</code> هو الإصدار الأدنى المتوافق مع المشروع، مع السماح بتحديث الحزمة في المستقل إلى أي إصدار يقلّ عن<code>3.0</code>.
</p>

<p>
	لن تحتاج في أغلب الحالات للتدخلّ وتحرير الملف <code>composer.json</code> لتعديل متطلّبات الإصدار يدويّا؛ إلا أنه توجد حالات يكون فيها هذا الأمر ضروريّا، كأن يُعلَن عن إصدار مهمّ من الحزمة يوفّر ميزات ترغب في الاستفادة منها أو عندما لا تتبع الحزمة التي تستخدمها ترقيما ذا دلالة متعارف عليه).
</p>

<p>
	يوضّح الجدول التالي أمثلة على تعريف القيود على الإصدارات في الملف <code>composer.json</code>. يظهر في العمود الأول القيدُ، وفي الثاني دلالة القيد وفي العمود الثالث أمثلة على إصدارات يسمح بها هذا القيد.
</p>

<pre class="ipsCode" id="ips_uid_3494_18">
Constraint    Meaning          Example Versions Allowed
^1.0          &gt;= 1.0 &lt; 2.0      	  1.0, 1.2.3, 1.9.9
^1.1.0        &gt;= 1.1.0 &lt; 2.0          1.1.0, 1.5.6, 1.9.9
~1.0          &gt;= 1.0 &lt; 2.0.0          1.0, 1.4.1, 1.9.9
~1.0.0        &gt;= 1.0.0 &lt; 1.1          1.0.0, 1.0.4, 1.0.9
1.2.1         1.2.1                   1.2.1
1.*           &gt;= 1.0 &lt; 2.0    	      1.0.0, 1.4.5, 1.9.9
1.2.*         &gt;= 1.2 &lt; 1.3            1.2.0, 1.2.3, 1.2.9</pre>

<p>
	يحوي <a href="https://getcomposer.org/doc/articles/versions.md" rel="external nofollow">التوثيق الرسمي</a> على شرح مفصّل حول طريقة طتابة القيود في الملف <code>composer.json</code>.
</p>

<h2 id="تضمين-سكربتات-تحمل-تلقائيا">
	تضمين سكربتات تُحمَّل تلقائيا
</h2>

<p>
	يتيح Composer إمكانيّة التحميل التلقائي لسكربتات PHP، فيتولّى تحميل الأصناف Classes التي ترغب بتوفرها تلقائيا في تطبيقك. يجعل هذا الأمر من التعامل مع الاعتمادات وإنشاء فضاءات أسماء خاصّة بك أسهل كثيرا.<br>
	كلّ ما تحتاجه لتحميل حزمة تلقائيا هو تضمين الملف <code>vendor/autoload.php</code> في سكربت PHP قبل استهلال Instantiation الصنف (لحظة إنشاء الكائن).
</p>

<p>
	نعود للتطبيق المثال <code>slugify</code>. سنستخدم محرر النصوص <code>nano</code> لإنشاء ملفّ باسم <code>test.php</code> داخل مجلّد المشروع الذي أنشأناه سابقا، من أجل استخدام <code>cocur/slugify</code>:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs avrasm"><span class="pln">nano test</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">php</span></span></code></pre>

<p>
	نضع المحتوى التالي في الملف <code>test.php</code>:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs xml"><span class="pln">    </span><span class="php"><span class="hljs-preprocessor"><span class="pun">&lt;?</span><span class="pln">php</span></span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">require</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">__DIR__</span></span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="hljs-string"><span class="str">'/vendor/autoload.php'</span></span><span class="pun">;</span><span class="pln">

    </span><span class="hljs-keyword"><span class="kwd">use</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">Cocur</span></span><span class="pln">\</span><span class="hljs-title"><span class="pln">Slugify</span></span><span class="pln">\</span><span class="hljs-title"><span class="pln">Slugify</span></span><span class="pun">;</span><span class="pln">

    </span><span class="hljs-variable"><span class="pln">$slugify</span></span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Slugify</span><span class="pun">();</span><span class="pln">

    </span><span class="hljs-keyword"><span class="pln">echo</span></span><span class="pln"> </span><span class="hljs-variable"><span class="pln">$slugify</span></span><span class="pun">-&gt;</span><span class="pln">slugify</span><span class="pun">(</span><span class="hljs-string"><span class="str">'Hello World, this is a long sentence and I need to make a slug from it!'</span></span><span class="pun">);</span></span></code></pre>

<p>
	يمكنك تشغيل السكربت من الطرفية على النحو التالي:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs avrasm"><span class="pln">php test</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="pln">php</span></span></code></pre>

<p>
	تظهر نتيجة التنفيذ التالية:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs lasso"><span class="pln">hello</span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">world</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="kwd">this</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="kwd">is</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">a</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="kwd">long</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">sentence</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="kwd">and</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">i</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">need</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">to</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">make</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">a</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">slug</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="kwd">from</span></span><span class="hljs-attribute"><span class="pun">-</span><span class="pln">it</span></span></code></pre>

<h2 id="تحديث-اعتمادات-المشروع">
	تحديث اعتمادات المشروع
</h2>

<p>
	يُستخدَم الأمر التالي لتحديث اعتمادات المشروع:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs sql"><span class="pln">composer </span><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">update</span></span></span></code></pre>

<p>
	سيتحقّق الأمر من وجود إصدارات جديدة من المكتبات البرمجيّة المطلوبة لمشروعك، فإن وجد إصدارا جديدا يتوافق مع القيود المعرَّفة ضمن الملف <code>composer.json</code> فسيضعه مكان الإصدارات المثبتة. سيُحدَّث الملف <code>composer.lock</code> ليوافق التغييرات الجديدة.
</p>

<p>
	يمكنك كذلك تحديد مكتبات لتحديثها، دون أن تحدّث كامل المشروع، وذلك بتمريرها إلى الأمر <code>composer update</code>:
</p>

<pre class="ipsCode" id="ips_uid_3494_9">
<code class="hljs sql"><span class="pln">composer </span><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">update</span></span><span class="pln"> vendor1</span><span class="pun">/</span><span class="pln">package1 vendor2</span><span class="pun">/</span><span class="pln">package2</span></span></code></pre>

<h2 id="خاتمة">
	خاتمة
</h2>

<p>
	أصبح استخدام Composer شائعا بين المطوّرين لدرجة أنه صار عمليًّا معيارا لتشارك المكتبات البرمجيّة واسكتشافها ممّا يعني أنه أداة ضروريّة لتكون من مجموعة الأدوات التي تعتمد عليها.
</p>

<p>
	ترجمة - بتصرّف - للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-composer-on-ubuntu-16-04" rel="external nofollow">How To Install and Use Composer on Ubuntu 16.04</a> لصاحبه Brennen Bearnes.
</p>
]]></description><guid isPermaLink="false">315</guid><pubDate>Fri, 12 May 2017 21:08:04 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x633;&#x62A;&#x62E;&#x62F;&#x645; &#x623;&#x648;&#x627;&#x645;&#x631; cd &#x648; pwd &#x648; ls &#x644;&#x627;&#x633;&#x62A;&#x643;&#x634;&#x627;&#x641; &#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x645;&#x644;&#x641;&#x627;&#x62A; &#x639;&#x644;&#x649; &#x646;&#x638;&#x627;&#x645; &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-%D8%A3%D9%88%D8%A7%D9%85%D8%B1-cd-%D9%88-pwd-%D9%88-ls-%D9%84%D8%A7%D8%B3%D8%AA%D9%83%D8%B4%D8%A7%D9%81-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%B9%D9%84%D9%89-%D9%86%D8%B8%D8%A7%D9%85-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r305/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_02/how-to-use-cd-pwd-and-ls.png.e7531de3f6a82c711fa788afa5272e98.png" /></p>

<h2>
	مقدمة
</h2>

<p>
	إن التعوّد على سطر الأوامر هي الخطوة الأولى نحو الاستفادة من قوة منصة خادوم لينكس، وهو شرط أساسي لجميع نشاطات المرتبطة بالخواديم والتي قد تتمنى القيام بها في هذه البيئة.
</p>

<p>
	على الرغم من وجود بدائل رسومية للعديد من الأدوات إلا أن تعلم سطر الأوامر مهارة ستسمح لك بالعمل بكفاءة وسرعة ومرونة بطريقة لا يمكنك فعلها مع أغلب الواجهات الرسومية (GUI).
</p>

<p>
	يجب علينا أن نبدء من مكان ما، لذلك في هذا المقال سوف نغطي الأساسيات: كيف تتنقل في النظام واكتشاف ما حولنا.
</p>

<p style="text-align: center;">
	<img alt="how-to-use-cd-pwd-and-ls.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22005" data-unique="oqnc1l28t" src="https://academy.hsoub.com/uploads/monthly_2017_02/how-to-use-cd-pwd-and-ls.png.32b50b3c8fce7057def7ba785e9ddb40.png" style=""></p>

<h1 id="متطلبات-أساسية">
	متطلبات أساسية
</h1>

<p>
	هذا المقال بسيط وأساسي، لذلك فهو لا يتطلب الكثير من المعرفة المسبقة، ومع ذلك، ستحتاج إلى تسجيل الدخول إلى خادومك الخاص لتبدأ الاستكشاف.
</p>

<p>
	الخيارات التي لديك للقيام بهذا تعتمد على نظام التشغيل الذي تستخدمه في المنزل.
</p>

<p>
	عندما تنشئ DigitalOcean droplet جديد، سوف يرسلون رسالة عبر البريد الإلكتروني تحتوي على كلمة السر و عنوان IP خاص للوصول إلى خادومك الجديد، استخدم هذا الرابط لمعرفة كيفية الاتصال بخادوم VPS الخاص بك.
</p>

<pre class="ipsCode" id="ips_uid_70_7">
<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr> root@your_IP</pre>

<p>
	وثمة خيار آخر عن طريق استخدام زر “Console Access” في الزاوية العلوية على اليمين من لوحة تحكم DigitalOcean، هذا الأمر سينشئ لك طرفية افتراضية مباشرة في نافذة متصفحك.
</p>

<h1 id="معرفة-موقعك-عن-طريق-pwd">
	معرفة موقعك عن طريق pwd
</h1>

<p>
	في هذه المرحلة، يجب أن تكون قد سجلت دخولك إلى خادوم لينكس الخاص بك، وسوف ترى في الغالب شيئا مشابهًا لهذا:
</p>

<pre class="ipsCode" id="ips_uid_70_9">
root@your_hostname:~# </pre>

<p>
	هذا هو الموجه (prompt) حيث نكتب الأوامر، وليس هذا فقط، بل أنت حاليا في مكان محدد في نظام ملفات الخادوم حيث ستكون دائما في مكان معين في التسلسل الهرمي للملفات وهذا الأمر يؤثر على كيفية عمل الأوامر التي تكتبها.
</p>

<p>
	هذا الأمر يشبه قيامك بفتح متصفح الملفات في حاسوبك المحلي، يمكنك الضغط على مختلف المجلدات للانتقال إلى مناطق مختلفة من نظام الملفات، وإذا ذهبت إلى قائمة التعديل (edit menu) في متصفح الملفات، سوف تجد بعض الخيارات التي ستُطبق على العناصر الموجودة في المجلد التي أنت فيه، وسطر الأوامر هو تمثيل نصي لنفس الفكرة.
</p>

<p>
	فأين نحن الآن بالضبط في نظام ملفاتنا؟ هنالك دليل واحد موجود في الموجه نفسه، فقبل رمز <code>#</code> أو <code>$</code> في نهاية الموجه (هذا سيعتمد على المستخدم الذي سجّل دخوله)، سوف ترى رمزًا خاصًا <code>~</code> وهذا يعني أنك موجود في مجلد المنزل (home).
</p>

<p>
	مجلد المنزل هو المكان الذي يتم تخزين ملفات المستخدم، فالرمز <code>~</code> هو اختصار لهذا المجلد.
</p>

<p>
	هنالك طريقة أخرى لمعرفة موقعنا في نظام الملفات وهي عن طريق استخدام الأمر <code>pwd</code> وهذا الأمر سيكون أول أمر سنتعلمه.
</p>

<p>
	اكتب هذه الحروف على الطرفية واضغط على زر الإدخال (Enter):
</p>

<pre class="ipsCode" id="ips_uid_70_11">
pwd

/root</pre>

<p>
	إن <code>/root</code> هو مجلد المنزل للمستخدم للمستخدم الجذر (المدير)، إذا كنت قد سجّلت دخولك باستخدام مستخدم آخر، فسوف ترى شيئًا مشابهًا لهذا:
</p>

<pre class="ipsCode" id="ips_uid_70_13">
pwd

/home/your_username</pre>

<p>
	في هذا الدرس، لا يهم المستخدم الذي سجّلت دخولك به، فأي من النتيجتين ظهرت لك فهي مناسبة.
</p>

<h1 id="النظر-حولك-باستخدام-ls">
	النظر حولك باستخدام ls
</h1>

<p>
	الآن أنت تعرف مكانك وفي أي مجلد أنت، لكن لازلت تجهل ما هي المحتويات الأخرى الموجودة في ذلك المجلد، فكيف تستطيع معرفة ذلك؟
</p>

<p>
	ببساطة يمكننا سؤال الخادوم عن الملفات والمجلدات الموجودة في المجلد الحالي عن طريق استخدام الأمر <code>ls</code>، أكتبه الآن على الموجه:
</p>

<pre class="ipsCode" id="ips_uid_70_15">
ls</pre>

<p>
	بعد كتابة هذا الأمر ستعود (في الغالب) إلى موجه الأوامر ولن تحصل على أية معلومات، فهل فشلت عملية تنفيذ هذا الأمر؟ لا، على العكس فقد نجحت لكنه ببساطة ليس هنالك أية ملفات أو مجلدات في مجلدك الحالي.
</p>

<p>
	دعونا ننشئ بعض ملفات التجريبية لنرى كيف يعمل الأمر <code>ls</code> عند وجود ملفات في المجلد، أكتب هذا الأمر لإنشاء بضعة ملفات:
</p>

<pre class="ipsCode" id="ips_uid_70_17">
touch file{1..5}</pre>

<p>
	السطر السابق سينشئ لنا 5 ملفات بأسماء <code>file1</code> و <code>file2</code>… في مجلدك الحالي.
</p>

<p>
	لنُجرب الأمر <code>ls</code> لنرى كيف سيتصرف الآن:
</p>

<pre class="ipsCode" id="ips_uid_70_19">
ls

file1  file2  file3  file4  file5</pre>

<p>
	رائع، تعرّف الآن أمر ls على الملفات الموجودة في مجلد المنزل.
</p>

<p>
	أغلب الأوامر لديها سلوكيات افتراضية يتم تنفيذها عند استدعائها كما فعلنا في الأعلى، ومع ذلك، فإن أغلب سلوكيات الأمر يمكن التحكم بها عن طريق تمرير المعاملات الاختيارية إليها، وهذه الأخيرة يشار إليها بأسماء عديدة مثل الخيارات “options” والمعاملات “arguments/parameters” والأعلام “flags”…
</p>

<p>
	في بعض الأحيان، هذه المعاملات تُفعّل الوظائف الاختيارية المتاحة من خلال الأمر وفي أحيان آخرى تحدد الكائن الذي يجب على الأمر أن يتجنبه.
</p>

<p>
	لنبدأ مع الحالة الأولى.
</p>

<h2 id="استكشاف-خيارات-ls">
	استكشاف خيارات ls
</h2>

<p>
	تقريبا جميع الأوامر تملك خيار المساعدة، وفي أغلب الأوقات يمكنك الوصول إليه عن طريق إضافة <code>--help</code> أو <code>-h</code> إلى نهاية الأمر، يمكنك الآن تجربة هذا مع أمر ls:
</p>

<pre class="ipsCode" id="ips_uid_70_21">
ls --help

Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

Mandatory arguments to long options are mandatory for short options too.
    -a, --all                  do not ignore entries starting with .
    -A, --almost-all           do not list implied . and ..
        --author               with -l, print the author of each file
    -b, --escape               print C-style escapes for nongraphic characters
        --block-size=SIZE      scale sizes by SIZE before printing them.  E.g.,
. . .</pre>

<p>
	سيعطيك هذا بعض الإرشادات حول الاستخدام الصحيح للأمر بالإضافة إلى لمحة حول الخيارات المتاحة لتغيير السلوك الإفتراضي للأوامر.
</p>

<p>
	العمود الأيسر يعطيك الحروف التي يجب كتابتها وتمريرها إلى الأمر لتنفيذ ما يوجد في وصف العمود الأيمن.
</p>

<p>
	إن <code>--help</code> التي قمنا بإضافتها هي مثال لخيار يمكننا تمريره.
</p>

<p>
	ومن الطرق الأخرى لمعرفة الخيارات المتاحة لأمر معين هي عن طريق التحقق من الدليل “manual”، ويمكنك فعل ذلك عن طريق كتابة <code>man</code> متبوعا بالأمر الذي تريد معرفة خياراته.
</p>

<p>
	قم بتجربة هذا الآن: 
</p>

<pre class="ipsCode" id="ips_uid_70_23">
man ls
</pre>

<p>
	يمكنك التنقل في الصفحة كما تشاء عن طريق مفاتيح الأسهم والخروج عن طريق كتابة <code>q</code>.
</p>

<p>
	كما ترى، يمتلك <code>ls</code> بضعة خيارات يمكنك تمريرها إلى الأمر لتغيير سلوكه، دعونا نجرب بعضها.
</p>

<pre class="ipsCode" id="ips_uid_70_25">
ls -l

-rw-r--r-- 1 root root 0 Feb 28 19:45 file1
-rw-r--r-- 1 root root 0 Feb 28 19:45 file2
-rw-r--r-- 1 root root 0 Feb 28 19:45 file3
-rw-r--r-- 1 root root 0 Feb 28 19:45 file4
-rw-r--r-- 1 root root 0 Feb 28 19:45 file5
</pre>

<p>
	السطر السابق يعرض لنا نفس الملفات الخمسة السابقة لكنه يعرضها بشكل أطول، وهذا الأمر يعطينا المزيد من المعلومات حول الملفات مثل المالك (“root” الأولى)، والمجموعة المالكة (“root” الثانية)، وحجم الملف (0) بالإضافة إلى تاريخ آخر تعديل وبعض المعلومات الأخرى.
</p>

<p>
	لنجرب خيارًا آخر:
</p>

<pre class="ipsCode" id="ips_uid_935_7">
ls -a

.   .aptitude      .bashrc  file2  file4  .profile  .<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>
..  .bash_history  file1    file3  file5  .rnd      .viminfo</pre>

<p>
	عرض لنا هذا الخيار ملفات لم نرها من قبل، إن المعامل <code>-a</code> مرادف للمعامل –all والذي يعرض لنا جميع الملفات الموجودة في المجلد الحالي بما في ذلك الملفات المخفية.
</p>

<p>
	في أنظمة لينكس، جميع الملفات التي يبدأ اسمها بنقطة سيتم إخفائها بشكل افتراضي، وهذه الملفات ليست سرية ويمكن لأي شخص إيجادها وتم الحفاظ عليها بهذه الطريقة لتسهيل عملية إدارة الملفات، وعند تمرير <code>-a</code> فسنأمر <code>ls</code> بعرض هذه الملفات المخفية أيضا.
</p>

<p>
	يمكننا تمرير عدة معاملات كذلك، وذلك عن طريق وضعهم معا كالتالي:
</p>

<pre class="ipsCode" id="ips_uid_70_27">
ls -l -a

drwx------  4 root root 4096 Feb 28 19:45 .
drwxr-xr-x 23 root root 4096 May  3  2013 ..
drwx------  2 root root 4096 Feb 28 17:19 .aptitude
-rw-------  1 root root 2036 Feb 28 18:20 .bash_history
-rw-r--r--  1 root root  570 Jan 31  2010 .bashrc
-rw-r--r--  1 root root    0 Feb 28 19:45 file1
. . .
</pre>

<p>
	الأمر السابق سيعمل بدون مشاكل، لكن يمكننا أيضا دمج المعاملات كالتالي: 
</p>

<pre class="ipsCode" id="ips_uid_70_29">
ls -la
</pre>

<p>
	هذه الطريقة ستعمل بالضبط كالطريقة الأولى وتتطلّب وقت أقل للكتابة.
</p>

<p>
	ومن الخيارات الأخرى المفيدة خيار <code>-R</code> والذي سيعرض جميع الملفات والمجلدات (ومحتوياتها)، وبما أن المجلدات الموجودة في مجلد المنزل الخاص بنا مخفية، فسنمرر خيار <code>-a</code> أيضا: 
</p>

<pre class="ipsCode" id="ips_uid_70_31">
ls -Ra

      .:
.   .aptitude      .bashrc  file2  file4  .profile  .<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>
..  .bash_history  file1    file3  file5  .rnd      .viminfo

./.aptitude:
.  ..  cache  config

./.<abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">ssh</abbr>:
.  ..  authorized_keys
</pre>

<p>
	الآن عرفنا كيف نغير سلوكيات <code>ls</code>، لنغير الآن “الكائن” الذي يعمل عليه <code>ls</code>.
</p>

<h2 id="استخدام-ls-في-مجلدات-أخرى">
	استخدام ls في مجلدات أخرى
</h2>

<p>
	افتراضيا، سيعرض <code>ls</code> محتويات المجلد الحالي، ومع ذلك يمكنك تمرير اسم أي مجلد تريد أن ترى محتوياته في نهاية الأمر.
</p>

<p>
	على سبيل المثال، يمكننا رؤية محتويات مجلد <code>/etc</code> الموجود في جميع أنظمة لينكس بكتابة السطر التالي: 
</p>

<pre class="ipsCode" id="ips_uid_70_33">
ls /etc

acpi            fstab        magic        rc.local
adduser.conf        fstab.d      magic.mime   rc.local.orig
aliases         fuse.conf    mailcap      rcS.d
aliases.db      gai.conf     mailcap.order    reportbug.conf
alternatives        groff        mailname     resolvconf
anacrontab      group        mail.rc      resolv.conf
apm         group-       manpath.config   rmt
. . .
</pre>

<p>
	كما ترى فإن هنالك الكثير من الملفات في هذا المجلد.
</p>

<p>
	أي مسار لمجلد يبدأ بخط مائل (/) يُعرف على أنه مسار “مطلق” وسبب ذلك أنه يشير إلى أعلى مسار المجلد والذي هو مجلد الجذر.
</p>

<p>
	ومن الطرق الأخرى للإشارة إلى مجلد هي عن طريق استخدام المسار “النسبي”، وهذا سوف يبحث عن مجلد نسبي مرتبط بالمجلد الذي تتواجد به أنت الآن، وهذه المجلدات لا تبدأ بخط مائل.
</p>

<p>
	لا نملك أية مجلدات غير مخفية في مجلدنا الحالي لذلك سننشئ بعضها بسرعة وسنضيف بعض الملفات داخلها، لا تقلق حول عدم فهمك لهذه الأوامر في الوقت الحالي، فهذه الأوامر لإنشاء ملفات فقط لاستعمالها في الاستكشاف، لذلك أُكتبها كما هي:
</p>

<pre class="ipsCode" id="ips_uid_70_35">
mkdir dir{1..3}
touch dir{1..3}/test{A,B,C}
</pre>

<p>
	سينشئ لنا هذا بعض المجلدات بداخلها ملفات، يمكننا رؤية هذه المجلدات باستخدام أمر <code>ls</code> عادي:
</p>

<pre class="ipsCode" id="ips_uid_70_37">
ls

dir1  dir2  dir3  file1  file2  file3  file4  file5
</pre>

<p>
	حتى نتمكن من رؤية ما بداخل مجلد <code>dir1</code>، يمكننا أن نعطي مسارًا مُطلقًا كما في المثال السابق، بإضافة المجلد الذي نريد رؤيته إلى نهاية قيمة مجلدنا الحالي، وسنتمكن من معرفة مجلدنا الحالي عن طريق الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_70_39">
pwd

/root
</pre>

<p>
	وبعد ذلك أضف المجلد الذي نهتم به إلى النهاية: 
</p>

<pre class="ipsCode" id="ips_uid_70_42">
ls /root/dir1

testA  testB  testC 
</pre>

<p>
	لم نكن مُجبرين على القيام بذلك، يمكننا ببساطة الإشارة إلى المجلدات الموجودة داخل مجلدنا الحالي بأسمائها فقط، كالتالي: 
</p>

<pre class="ipsCode" id="ips_uid_70_44">
ls dir1

testA  testB  testC
</pre>

<p>
	إذا لم نبدأ المسار بخط مائل، فسيبحث نظام التشغيل على المسار المجلد الذي يبدأ بمجلدنا الحالي.
</p>

<h1 id="التجوال-في-المكان">
	التجوال في المكان
</h1>

<p>
	حتى الآن، تعلمنا كيف نجد موقعنا في نظام الملفات كما أننا تعلمنا كيف نستخدم الأمر <code>ls</code> لمعرفة بعض المعلومات حول الملفات الموجودة في مجلدات معينة.
</p>

<p>
	لكن كيف نغيّر مجلد عملنا؟ تغيير مجلد عملنا سيسمح لنا باستخدام مسارات مترابطة من أماكن مختلفة ﻷنه في العادة، سيكون من السهل إدارة الملفات في المجلد الذي يحتويها.
</p>

<p>
	يمكننا التنقل حول التسلسل الهرمي للملفات باستخدام الأمر <code>cd</code>، هذا الأمر يغيّر المجلد الحالي إلى أي مجلد آخر.
</p>

<p>
	هذا أبسط استخدام لهذا الأمر:
</p>

<pre class="ipsCode" id="ips_uid_70_46">
cd
</pre>

<p>
	لا يبدو أن هنالك أية نتيجة، في الحقيقة، لم يحدث أي شيء، فعند تنفيذ الأمر <code>cd</code> بدون معلومات إضافية فسيغير موقعك الحالي إلى مجلد المنزل، وبما أننا في مجلد المنزل فلن يقوم الأمر بأي شيء.
</p>

<p>
	الطريقة الأساسية لاستخدام هذا الأمر هي كالتالي: 
</p>

<pre class="ipsCode" id="ips_uid_70_48">
cd /path/to/directory
</pre>

<p>
	في هذا المثال، يمكنك استبدال <code>/path/to/directory</code> بمسار المجلد الذي تريد الانتقال إليه، فعلى سبيل المثال، إذا أردت الانتقال إلى مجلد الجذر، والذي سيكون مساره مجرد خط مائل <code>/</code> لأنه في أعلى شجرة الملفات، يمكننا كتابة التالي:
</p>

<pre class="ipsCode" id="ips_uid_70_50">
cd /
</pre>

<p>
	ملاحظة: المجلد الجذر (الذي أشرنا إليه بخط مائل <code>/</code>) يختلف عن مجلد المنزل للمستخدم الجذر (الموجود في <code>/root</code>)، وهذا الأمر سيربكك في البداية، لكن تذكر فقط أن المجلد الأعلى في شجرة نظام الملفات يدعى بالجذر.
</p>

<p>
	ستلاحظ أن موجه الأوامر قد تغير، بالضبط قبل رموز <code>#</code> أو <code>$</code>، فالمجلد قد تغير من <code>~</code> (تذكر أن رمز <code>~</code> يشير إلى مجلد المنزل للمستخدم) إلى مجلد الجذر لنظام الملفات.
</p>

<p>
	يمكننا التأكد من موقعنا عن طريق استخدام الأمر <code>pwd</code> مرة أخرى: 
</p>

<pre class="ipsCode" id="ips_uid_70_52">
pwd

/
</pre>

<p>
	كما يمكننا التحقق من الملفات الموجودة في مجلدنا الجديد: 
</p>

<pre class="ipsCode" id="ips_uid_70_54">
ls

bin   etc     lib         media  proc  sbin     sys  var
boot  home    lib64       mnt    root  selinux  tmp  vmlinuz
dev   initrd.img  lost+found  opt    run   srv      usr
</pre>

<p>
	نجحنا بالتحرك نحو مكان جديد، لنحاول الآن الانتقال إلى مجلد جديد باستخدام المسار النسبي (relative path)، هنالك مجلد يدعى usr داخل مجلدنا الحالي، لننتقل إليه عن طريق كتابة:
</p>

<pre class="ipsCode" id="ips_uid_70_56">
cd usr
</pre>

<p>
	كما ترون، يمكننا استخدام المسار النسبي مع cd أيضا، والآن كيف نستطيع العودة إلى مجلد الجذر مرة أخرى؟ يمكننا كتابة نفس الأمر الذي استخدمناه سابقا <code>cd /</code>، لكننا سنجرب شيئًا مُختلفًا.
</p>

<p>
	لنجرب الانتقال إلى أعلى الشجرة باستخدام المسارات النسبيّة، فكيف نشير إلى المجلد الذي يحتوي مجلدنا الحالي باستخدام المسارات النسبيّة؟
</p>

<p>
	ببساطة يمكننا الإشارة إلى المجلد الذي يحتوي على مجلدنا الحالي والذي يدعى بمجلد الأب باستخدام نقطتين (..).
</p>

<p>
	لنعد بمقدار مستوى واحد إلى الأعلى:
</p>

<pre class="ipsCode" id="ips_uid_70_58">
cd ..
pwd

/
</pre>

<p>
	كما ترى عدنا إلى مجلد الجذر.
</p>

<p>
	يمكننا أيضا الإشارة إلى مجلدنا الحالي باستخدام نقطة واحدة: 
</p>

<pre class="ipsCode" id="ips_uid_70_60">
ls .

bin   etc     lib         media  proc  sbin     sys  var
boot  home    lib64       mnt    root  selinux  tmp  vmlinuz
dev   initrd.img  lost+found  opt    run   srv      usr
</pre>

<p>
	ستكون هذه مفيدة جدا في العديد من الحالات والتي لن نتعلمها في هذه المرحلة لكنك ستتمكن من الإشارة إلى مجلدك الحالي بسهولة في مراحل لاحقة.
</p>

<p>
	كما قلنا سابقا، إن رمز “~” يشير إلى مجلد المنزل، لنستخدم ذلك كبداية لمسار مجلد “dir1” الموجود داخل مجلد المنزل:
</p>

<pre class="ipsCode" id="ips_uid_70_62">
cd ~/dir1
pwd

/root/dir1
</pre>

<p>
	انتقلنا الآن إلى مجلد داخل مجلد المنزل بطريقة سهلة باستخدام رمز “~” التي وضعناها في الجزء الأول من المسار.
</p>

<p>
	لكن ماذا لو نسيت القيام بشيء في المجلد السابق وتريد العودة إليه؟ يمككنا العودة إلى مجلدنا السابق بكتابة التالي:
</p>

<pre class="ipsCode" id="ips_uid_70_64">
cd -
pwd

/
</pre>

<p>
	عدنا إلى مجلدنا السابق.
</p>

<p>
	لنختم الدرس بالعودة إلى مجلد المنزل، يمكننا فعل ذلك باستخدام <code>~</code> كمسار للتبديل أو يمكنك أيضا استخدام الوضع الافتراضي لـ <code>cd</code> للعودة إلى مجلد المنزل إذا لم نضف أي مسار إلى الأمر، لنجرب ذلك:
</p>

<pre class="ipsCode" id="ips_uid_70_66">
cd
pwd

/root
</pre>

<p>
	كما ترى، نجحنا في العودة إلى مجلد المنزل.
</p>

<h1 id="الخاتمة">
	الخاتمة
</h1>

<p>
	ستمتلك الآن الأدوات التي تحتاجها لاستكشاف نظام الملفات، فعلى الرغم من أنك لم تكتشف كيف تقرأ الملفات إلا أنك أصبحت قادرا على التجوال وتصفح النظام بسهولة بالإضافة إلى قدرتك على معرفة مكانك والملفات حولك.
</p>

<p>
	ترجمة -وبتصرف- للمقال: <a href="https://www.digitalocean.com/community/tutorials/how-to-use-cd-pwd-and-ls-to-explore-the-file-system-on-a-linux-server" rel="external nofollow">How To Use cd, pwd, and ls to Explore the File System on a Linux Server</a> لصاحبه Justin Ellingwood
</p>
]]></description><guid isPermaLink="false">305</guid><pubDate>Tue, 28 Feb 2017 08:17:00 +0000</pubDate></item><item><title>&#x625;&#x62F;&#x627;&#x631;&#x629; &#x628;&#x64A;&#x626;&#x629; KVM &#x628;&#x623;&#x62F;&#x648;&#x627;&#x62A; &#x633;&#x637;&#x631; &#x627;&#x644;&#x623;&#x648;&#x627;&#x645;&#x631;</title><link>https://academy.hsoub.com/devops/linux/%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A8%D9%8A%D8%A6%D8%A9-kvm-%D8%A8%D8%A3%D8%AF%D9%88%D8%A7%D8%AA-%D8%B3%D8%B7%D8%B1-%D8%A7%D9%84%D8%A3%D9%88%D8%A7%D9%85%D8%B1-r289/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_02/kvm-4.png.e2adf17e0c5be0ded7750bba3ef1a9eb.png" /></p>

<p>
	سنعرض في هذا الدرس، الرابع من سلسلة دروس الحوسبة الافتراضية باستخدام KVM، كيفية إدارة الآلات الافتراضية عن طريق أدوات تعمل على سطر الأوامر؛ بدلا من <a href="https://academy.hsoub.com/devops/linux/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-kvm-%D9%88%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D8%A2%D9%84%D8%A7%D8%AA-%D8%A7%D9%81%D8%AA%D8%B1%D8%A7%D8%B6%D9%8A%D8%A9-virtual-machines-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85%D9%87-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-r286/" rel="">واجهة virt-manager الرسومية</a>. تفيد أدوات سطر الأوامر خصوصا في كتابة السكربتات <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D9%83%D8%AA%D8%A7%D8%A8%D8%A9-%D8%B3%D9%83%D8%B1%D8%A8%D8%AA%D8%A7%D8%AA-%D8%A7%D9%84%D8%B5%D8%AF%D9%81%D8%A9-shell-scripts-r252/" rel="">لأتمتة Automating</a> المهام. سنرى الأدوات التاليّة:
</p>

<ul>
<li>
		<code>virt-install</code>: لإنشاء الآلات الافتراضية وضبطها.
	</li>
	<li>
		<code>virsh</code>: لإنشاء مجامع التخزين وإعدادها.
	</li>
	<li>
		<code>qemu-img</code>: لإدارة تجزئات التخزين الافتراضية.
	</li>
</ul>
<p style="text-align: center;">
	<img alt="kvm-4.png" class="ipsImage ipsImage_thumbnailed" data-fileid="21682" data-unique="kvmu3m8y1" src="https://academy.hsoub.com/uploads/monthly_2017_02/kvm-4.png.43583f5130bc0cb74216e95944d19b4a.png" style=""></p>

<h2 id="إعداد-مجمع-تخزين">
	إعداد مجمع تخزين
</h2>

<p>
	تُعد أداة <code>virsh</code> على سطر الأوامر واجهةً لإدارة الآلات الافتراضية وإعدادها. سنستخدم هذه الأداة في الفقرات المقبلة لإنشاء مجمع تخزين لبيئة KVM. ننفذ الأمر <code>pool-define-as</code> مع <code>virsh</code> لتعريف مجمع تخزين جديد. نمرّر للأمر اسم المجمع، نوعه ومعطيات النوع. يبلغ عدد معطيات نوع المجمع خمسة، وتختلف معطيات نوع المجمع التي يجب تمريرها إلى الأمر من نوع إلى أخر. إن أردنا - مثلا - إنشاء مجمع تخزين مماثل للمجمع <code>SPool1</code> الذي أنشأناه في الدرس الماضي ، والذي هو من نوع <code>dir</code> فسنحتاج لذكر المعطى <code>target</code> (الأخير من المعطيات الخمسة، ويشير إلى مسار مجلّد على النظام المضيف) فقط ونعوّض المعطيات الأربعة المتبقية بعلامة <code>-</code>:
</p>

<pre class="ipsCode" id="ips_uid_7089_7">
$ sudo virsh pool-define-as SPool1CL dir - - - - "/mnt/spools/Spool1New"
Pool SPool1CL defined</pre>

<p>
	تظهر بعد تنفيذ الأمر رسالة توضّح أن مجمع التخزين قد عُرِّف.
</p>

<p>
	<strong>ملحوظة:</strong> أسمينا مجمع التخزين <code>SPool1CL</code> لتمييزه عن مجمع التخزين الذي أنشأناه في <a href="https://academy.hsoub.com/devops/linux/%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D9%88%D8%B3%D8%A7%D8%A6%D8%B7-%D8%A7%D9%84%D8%AA%D8%AE%D8%B2%D9%8A%D9%86-%D8%A7%D9%84%D8%A7%D9%81%D8%AA%D8%B1%D8%A7%D8%B6%D9%8A%D8%A9-%D9%81%D9%8A-%D8%A8%D9%8A%D8%A6%D8%A9-kvm-r288/" rel="">الدرس السابق</a>.
</p>

<p>
	يمكننا سرد جميع مجامع التخزين المتوفّرة على النظام بتمرير المعطى <code>all--</code> إلى الأمر <code>virsh pool-list</code>:
</p>

<pre class="ipsCode" id="ips_uid_7089_9">
$ sudo virsh pool-list --all
Name                 State      Autostart 
-------------------------------------------
default              active     yes       
SPool1               active     yes       
SPool1CL             inactive   no        
SPool2               active     yes</pre>

<p>
	ستلاحظ ظهور مجمع التخزين <code>SPool1CL</code> إلى جانب مجامع التخزين التي أنشأناها في الدرس الماضي؛ لكنّه يختلف عنها في الحالة <code>State</code> والتفعيل التلقائي (<code>Autostart</code>). في الواقع، الأمر السابق يعرّف مجمع تخزين، ولكنه لا ينشئه فعليا. ننفّذ الأمر <code>virsh pool-build</code> لإنشاء مجمع التخزين <code>SPool1CL</code> المعرَّف أعلاه:
</p>

<pre class="ipsCode" id="ips_uid_7089_11">
$ sudo virsh pool-build SPool1CL
Pool SPool1CL built</pre>

<p>
	تظهر بعد تنفيذ الأمر رسالة تخبرنا بإنشاء المجمع <code>SPool1CL</code>. يمكننا الآن تفعيل <code>SPool1CL</code> (تغيير الحالة من خامل <code>inactive</code> إلى نشِط <code>active</code>):
</p>

<pre class="ipsCode" id="ips_uid_7089_13">
$ sudo virsh pool-start SPool1CL
Pool SPool1CL started</pre>

<p>
	إن أعدنا سرد جميع مجامع التخزين في النظام فسنلاحظ تغيّر حالة <code>SPool1CL</code> من <code>inactive</code> إلى <code>active</code>:
</p>

<pre class="ipsCode" id="ips_uid_7089_15">
$ sudo virsh pool-list --all
Name                 State      Autostart 
-------------------------------------------
default              active     yes       
SPool1               active     yes       
SPool1CL             active     no        
SPool2               active     yes</pre>

<p>
	بقي لنا تفعيل التفعيل التلقائي لـ<code>SPool1CL</code> بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode" id="ips_uid_7089_17">
$ sudo virsh pool-autostart SPool1CL
Pool SPool1CL marked as autostarted</pre>

<p>
	فلنعرض معلومات مفصّلة عن مجمع التخزين الذي أكملنا إنشاءه للتو:
</p>

<pre class="ipsCode" id="ips_uid_7089_19">
$ sudo virsh pool-info SPool1CL
Name:           SPool1CL
UUID:           120247f3-669c-4868-8c1e-bbd134077f55
State:          running
Persistent:     yes
Autostart:      yes
Capacity:       184.33 GiB
Allocation:     17.90 GiB
Available:      166.43 GiB</pre>

<p>
	مجمع التخزين <code>SPool1CL</code> جاهز الآن للاستخدام. يُضبَط مجمع تخزين جديد إذن على خطوات: التعريف <code>pool-define-as</code>، الإنشاء <code>pool-build</code>، التفعيل <code>pool-start</code> والتفعيل التلقائي <code>pool-autostart</code>.
</p>

<h2 id="إعداد-تجزئات-تخزين-افتراضية">
	إعداد تجزئات تخزين افتراضية
</h2>

<p>
	حان الآن دور التجزئات الافتراضية التي نستخدم الأداة <code>qemu-img</code> لإعدادها. سننشئ بهذه الأداة تجزئة افتراضية جديدة على مجمع التخزين <code>SPool1CL</code>. نحدّد للأداة الأمر الذي نريد تنفيذه (<code>create</code> بالنسبة للإنشاء)، صيغة تجزئة التخزين، مسار الملفّ الخاصّ بالتجزئة وحجمها:
</p>

<pre class="ipsCode" id="ips_uid_7089_21">
$ sudo qemu-img create -f raw /mnt/spools/Spool1New/SVol1.img 10G
Formatting '/mnt/spools/Spool1New/SVol1.img', fmt=raw size=10737418240</pre>

<p>
	لاحظ أن مسار الملفّ الخاصّ بالتجزئة <code>mnt/spools/Spool1New/SVol1.img/</code> يوجد ضمن المجلّد <code>mnt/spools/Spool1New/</code> الخاصّ بمجمع التخزين الذي أنشأناه أعلاه (تذكّر أننا حدّدنا النوع <code>dir</code>، الذي يحفظ التجزئات الافتراضية ضمن مجلد يوجد في نظام التشغيل).
</p>

<p>
	يمكن التحقّق من خاصيّات التجزئة بتنفيذ الأمر <code>qemu-img info</code>:
</p>

<pre class="ipsCode" id="ips_uid_7089_23">
$ sudo qemu-img info /mnt/spools/Spool1New/SVol1.img
image: /mnt/spools/Spool1New/SVol1.img
file format: raw
virtual size: 10G (10737418240 bytes)
disk size: 0</pre>

<p>
	<strong>تحذير:</strong> تجنّب استخدام الأمر <code>qemu-img</code> للتعديل على تجزئات تستخدمها آلالات افتراضية نشطة، أو أي عمليّة Process أخرى؛ فقد يؤدي ذلك إلى إفساد التجزئة.
</p>

<h2 id="إنشاء-آلات-افتراضية">
	إنشاء آلات افتراضية
</h2>

<p>
	الخطوة الأخيرة هي إنشاء آلة افتراضية وتثبيت نظام تشغيل عليها؛ نستخدم الأداة <code>virt-install</code> لهذا الغرض. يتطلّب إنشاء آلة افتراضية جديدة تمرير المعطيات التاليّة إلى الأمر <code>virt-install</code>:
</p>

<ul>
<li>
		اسم الآلة الافتراضية <code>name--</code>.
	</li>
	<li>
		مسار التجزئة التي نريد استخدامها مع الآلة الافتراضية <code>disk path--</code>.
	</li>
	<li>
		كيفية الاتصال بالآلة الافتراضية <code>graphics--</code>. تكون هذه القيمة عادة <code>spice</code> (اسم برمجية للتخاطب مع أسطح المكتب الافتراضية، موجودة في حزمة <code>libvirt-bin</code>).
	</li>
	<li>
		عدد المعالجات الافتراضية <code>vcpu--</code>.
	</li>
	<li>
		حجم الذاكرة العشوائية بالميغابايت <code>ram--</code>.
	</li>
	<li>
		مسار ملفّ ISO المستخدَم لتثبيت نظام التشغيل الضيف على الآلة الافتراضية <code>cdrom--</code>.
	</li>
	<li>
		<p>
			واجهة الشبكة الافتراضية <code>network--</code>.
		</p>

		<p>
			 
		</p>
	</li>
</ul>
<pre class="ipsCode" id="ips_uid_7089_25">
$ sudo virt-install --name=win7 --disk path=/mnt/spools/Spool1New/SVol1.img --graphics spice --vcpu=2 --ram=4096 --cdrom=/home/zeine77/Documents/ISOs/GRMCULFRER_FR_DVD.iso --network bridge=virbr0</pre>

<p>
	يبدأ بعد تنفيذ الأمر إنشاءُ الآلة الافتراضية.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="19548" href="https://academy.hsoub.com/uploads/monthly_2016_10/01.png.e31743a11014f813bb839a24bd673051.png" rel=""><img alt="01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="19548" data-unique="6z0r59r35" src="https://academy.hsoub.com/uploads/monthly_2016_10/01.thumb.png.b1dc550da57204b42e2782e3ed4b709c.png"></a>
</p>

<p>
	ثم تظهر نافذة منبثقة جديدة لبدء تثبيت نظام التشغيل الضيف.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="19549" href="https://academy.hsoub.com/uploads/monthly_2016_10/02.png.f04ef8733cae4e22dbd5f203e76ab917.png" rel=""><img alt="02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="19549" data-unique="zkn0vbia6" src="https://academy.hsoub.com/uploads/monthly_2016_10/02.thumb.png.1d4b8669574693d38a40e4a4533881ca.png"></a>
</p>

<p>
	ترجمة - بتصرّف - لمقال <a href="http://www.tecmint.com/kvm-management-tools-to-manage-virtual-machines/" rel="external nofollow">How to Manage KVM Virtual Environment using Commandline Tools in Linux</a> لصاحبه Mohammad Dosoukey.
</p>
]]></description><guid isPermaLink="false">289</guid><pubDate>Sun, 19 Feb 2017 09:18:00 +0000</pubDate></item></channel></rss>
