عشرات الحيل مع قذيفة لينكس والتي يمكن أن توفر وقتك



  • بادئ ذي بدء ، يمكنك قراءة هذه المقالة باللغة الروسية هنا .

في إحدى الأمسيات ، كنت أقرأ إتقان التعبيرات العادية لجيفري فريدل ، أدركت أنه حتى لو كان لديك كل الوثائق والكثير من الخبرة ، يمكن أن يكون هناك الكثير من الحيل التي طورها أشخاص مختلفون وسجنوا لأنفسهم. كل الناس مختلفون. قد لا تكون التقنيات الواضحة بالنسبة لبعض الأشخاص واضحة للآخرين وتبدو وكأنها نوع من السحر الغريب لشخص ثالث. بالمناسبة ، لقد سبق أن وصفت العديد من هذه اللحظات هنا (باللغة الروسية) .

بالنسبة للمسؤول أو المستخدم ، فإن سطر الأوامر ليس فقط أداة يمكنها القيام بكل شيء ، ولكنها أيضًا أداة مخصصة للغاية يمكن تطويرها إلى الأبد. في الآونة الأخيرة ، كان هناك مقال مترجم حول بعض الحيل المفيدة في CLI. لكنني أشعر أن المترجم ليس لديه خبرة كافية مع CLI ولم يتبع الحيل الموصوفة ، لذلك يمكن تفويت العديد من الأشياء المهمة أو إساءة فهمها.

تحت خفض - عشرات الحيل في قذيفة لينكس من تجربتي الشخصية.

ملاحظة: تم تبسيط جميع البرامج النصية والأمثلة الواردة في المقال بشكل خاص قدر الإمكان - لذلك ربما يمكنك العثور على العديد من الحيل تبدو عديمة الفائدة تمامًا - ربما هذا هو السبب. ولكن على أي حال ، شارك عقلك في التعليقات!

1. سبليت سلسلة مع التوسعات المتغيرة


غالبًا ما يستخدم الأشخاص المقطوعين أو حتى المبتعدين فقط لاستبدال جزء من الخيط بنمط أو بفواصل.
أيضًا ، يستخدم العديد من الأشخاص عملية bash الفرعية باستخدام $ {VARIABLE: start_position: length} ، والذي يعمل بسرعة كبيرة.

لكن bash يوفر طريقة فعالة للتعامل مع سلاسل النص باستخدام # و ## و٪ و ٪٪ - يطلق عليها توسعات متغير bash .
باستخدام بناء الجملة هذا ، يمكنك قطع المحتاج حسب النموذج دون تنفيذ أوامر خارجية ، لذلك سيعمل بسرعة كبيرة.

يوضح المثال التالي كيفية الحصول على العمود الثالث (shell) من السلسلة حيث القيم مفصولة بنقطتين "اسم المستخدم: homedir: shell" باستخدام القص أو باستخدام التوسعات المتغيرة (نستخدم الأمر *: mask و ## ، مما يعني: cut جميع الشخصيات إلى اليسار حتى آخر القولون وجدت):

$ STRING="username:homedir:shell" $ echo "$STRING"|cut -d ":" -f 3 shell $ echo "${STRING##*:}" shell 

الخيار الثاني لا يبدأ العملية الفرعية ( المقطوعة ) ، ولا يستخدم الأنابيب على الإطلاق ، والتي يجب أن تعمل بشكل أسرع. وإذا كنت تستخدم نظام bash الفرعي على النوافذ ، حيث تتحرك الأنابيب بالكاد ، فسيكون فرق السرعة كبيرًا .

دعونا نرى مثالاً على Ubuntu - نفذ أمرنا في حلقة لمدة 1000 مرة

 $ cat test.sh #!/usr/bin/env bash STRING="Name:Date:Shell" echo "using cut" time for A in {1..1000} do cut -d ":" -f 3 > /dev/null <<<"$STRING" done echo "using ##" time for A in {1..1000} do echo "${STRING##*:}" > /dev/null done 

النتائج
 $ ./test.sh using cut real 0m0.950s user 0m0.012s sys 0m0.232s using ## real 0m0.011s user 0m0.008s sys 0m0.004s 

الفرق هو عشرات المرات!

بالطبع ، المثال أعلاه مصطنع للغاية. في المثال الحقيقي ، لن نعمل مع سلسلة ثابتة ، نريد قراءة ملف حقيقي. ولأمر " cut " ، نعيد توجيه / etc / passwd إليه فقط. في حالة ## ، يتعين علينا إنشاء حلقة وقراءة الملف باستخدام أمر داخلي " read ". فمن سيفوز في هذه القضية؟

 $ cat test.sh #!/usr/bin/env bash echo "using cut" time for count in {1..1000} do cut -d ":" -f 7 </etc/passwd > /dev/null done echo "using ##" time for count in {1..1000} do while read do echo "${REPLY##*:}" > /dev/null done </etc/passwd done 
نتيجة
 $ ./test.sh $ ./test.sh using cut real 0m0.827s user 0m0.004s sys 0m0.208s using ## real 0m0.613s user 0m0.436s sys 0m0.172s 
لا توجد تعليقات =)

بضعة أمثلة أخرى:

استخرج القيمة بعد الحرف المتساوي:

 $ VAR="myClassName = helloClass" $ echo ${VAR##*= } helloClass 

استخراج النص بين قوسين دائريين:

 $ VAR="Hello my friend (enemy)" $ TEMP="${VAR##*\(}" $ echo "${TEMP%\)}" enemy 

2. باش الإكمال التلقائي مع علامة التبويب


تعتبر حزمة bash-finished جزءًا من كل توزيعات Linux تقريبًا. يمكنك تمكينه في /etc/bash.bashrc أو /etc/profile.d/bash_completion.sh ، ولكن عادة ما يتم تمكينه افتراضيًا. بشكل عام ، يعد الإكمال التلقائي أحد اللحظات المريحة الأولى على نظام Linux shell التي يلتقي بها الوافد الجديد أولاً.

ولكن حقيقة أن ليس كل شخص يستخدم كل ميزات bash-finish ، وفي رأيي هو عبثا. على سبيل المثال ، لا يعلم الجميع ، أن الإكمال التلقائي لا يعمل فقط مع أسماء الملفات ، ولكن أيضًا مع الأسماء المستعارة والأسماء المتغيرة وأسماء الوظائف وبعض الأوامر حتى مع الوسيطات. إذا قمت بالبحث في البرامج النصية للإكمال التلقائي ، والتي هي في الواقع نصوص مقلدة ، فيمكنك إضافة الإكمال التلقائي للتطبيق أو البرنامج النصي الخاص بك.
ولكن دعنا نعود إلى الأسماء المستعارة.

لا تحتاج إلى تحرير PATH variable أو إنشاء ملفات في الدليل المحدد لتشغيل الاسم المستعار. تحتاج فقط لإضافتها إلى ملف تعريف أو بدء التشغيل وتنفيذها من أي مكان.

عادةً ما نستخدم أحرفًا صغيرة للملفات والدلائل الموجودة في * nix ، لذلك قد يكون من المريح جدًا إنشاء أسماء مستعارة كبيرة - في هذه الحالة ، فإن إتمام bash سيكمل أمرك بحرف واحد تقريبًا:

 $ alias TAsteriskLog="tail -f /var/log/asteriks.log" $ alias TMailLog="tail -f /var/log/mail.log" $ TA[tab]steriksLog $ TM[tab]ailLog 

3. باش الإكمال التلقائي مع علامة التبويب - الجزء 2


بالنسبة للحالات الأكثر تعقيدًا ، ربما ترغب في وضع البرامج النصية الشخصية على $ HOME / bin.
ولكن لدينا وظائف في باش.

وظائف لا تتطلب مسار أو ملفات منفصلة. و (الاهتمام) باش الانتهاء يعمل مع وظائف أيضا.

لنقم بإنشاء وظيفة LastLogin في .profile (لا تنسَ إعادة تحميل .profile):

 function LastLogin { STRING=$(last | head -n 1 | tr -s " " " ") USER=$(echo "$STRING"|cut -d " " -f 1) IP=$(echo "$STRING"|cut -d " " -f 3) SHELL=$( grep "$USER" /etc/passwd | cut -d ":" -f 7) echo "User: $USER, IP: $IP, SHELL=$SHELL" } 

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

في وحدة التحكم (يرجى ملاحظة أن اسم الوظيفة يحتوي على حرف كبير أولي لتسريع إكمال bash):

 $ L[tab]astLogin User: saboteur, IP: 10.0.2.2, SHELL=/bin/bash 

4.1. البيانات الحساسة


إذا وضعت مساحة قبل أي أمر في وحدة التحكم ، فلن تظهر في سجل الأوامر ، لذلك إذا كنت بحاجة إلى وضع كلمة مرور نص عادي في الأمر ، فهذه طريقة جيدة لاستخدام هذه الميزة - انظر إلى المثال التالي ، echo "hello 2 " لن تظهر في التاريخ:

 $ echo "hello" hello $ history 2 2011 echo "hello" 2012 history 2 $ echo "my password secretmegakey" # there are two spaces before 'echo' my password secretmegakey $ history 2 2011 echo "hello" 2012 history 2 

إنه اختياري
عادة ما يتم تمكينه افتراضيًا ، ولكن يمكنك تكوين هذا السلوك في المتغير التالي:

تصدير HISTCONTROL = التجاهل


4.2. البيانات الحساسة في وسيطات سطر الأوامر


تريد تخزين بعض البرامج النصية shell في git لمشاركتها عبر الخوادم ، أو قد تكون جزءًا من البرنامج النصي لبدء تشغيل التطبيق. وتريد أن يتصل هذا البرنامج النصي بقاعدة البيانات أو يفعل أي شيء آخر يتطلب بيانات اعتماد.

بالطبع ، من الجيد تخزين بيانات الاعتماد في البرنامج النصي نفسه ، لأن البوابة ليست آمنة.

عادةً يمكنك استخدام المتغيرات ، التي تم تعريفها بالفعل في البيئات المستهدفة ، ولن يحتوي البرنامج النصي على كلمات المرور نفسها.

على سبيل المثال ، يمكنك إنشاء برنامج نصي صغير في كل البيئات مع 700 أذونات والاتصال به باستخدام الأمر source من البرنامج النصي الرئيسي:

 secret.sh PASSWORD=LOVESEXGOD 

 myapp.sh source ~/secret.sh sqlplus -l user/"$PASSWORD"@database:port/sid @mysqfile.sql 

لكنها ليست آمنة.

إذا تمكن شخص آخر من تسجيل الدخول إلى مضيفك ، فيمكنه فقط تنفيذ الأمر ps ومشاهدة عملية sqlplus الخاصة بك باستخدام وسيطات سطر الأوامر بأكملها بما في ذلك كلمات المرور. لذلك ، يجب أن تكون الأدوات الآمنة عادةً قادرة على قراءة كلمات المرور / المفاتيح / البيانات الحساسة مباشرة من الملفات.

على سبيل المثال - آمن ssh فقط حتى لا يكون لديك خيارات لتوفير كلمة المرور في سطر الأوامر. ولكن يمكنه قراءة مفتاح ssh من الملف (ويمكنك تعيين أذونات آمنة على ملف مفتاح ssh).

و wget غير آمنة لديها خيار "- كلمة المرور" والذي يسمح لك بتوفير كلمة مرور في سطر الأوامر. وسيتم تشغيل wget طوال الوقت ، يمكن للجميع تنفيذ الأمر ps ورؤية كلمة المرور التي قدمتها.

بالإضافة إلى ذلك ، إذا كان لديك الكثير من البيانات الحساسة ، وتريد التحكم فيها من بوابة ، فإن الطريقة الوحيدة هي التشفير. لذلك وضعت كلمة السر الرئيسية لكل بيئة مستهدفة ، وجميع البيانات الأخرى التي يمكنك تشفيرها ووضعها في بوابة. ويمكنك العمل مع البيانات المشفرة من سطر الأوامر ، وذلك باستخدام openssl واجهة CLI. فيما يلي مثال لتشفير وفك تشفير من سطر الأوامر:

يحتوي ملف secret.key على المفتاح الرئيسي - سطر واحد:

 $ echo "secretpassword" > secret.key; chmod 600 secret.key 

يتيح استخدام aes-256-cbc لتشفير سلسلة:

 $ echo "string_to_encrypt" | openssl enc -pass file:secret.key -e -aes-256-cbc -a U2FsdGVkX194R0GmFKCL/krYCugS655yLhf8aQyKNcUnBs30AE5lHN5MXPjjSFML 

يمكنك وضع هذه السلسلة المشفرة في أي ملف تكوين مخزّن في git ، أو أي مكان آخر - دون secret.key يكاد يكون من المستحيل فك تشفيره.
لفك تشفير تنفيذ نفس الأمر ، فقط استبدل -e بـ -d:

 $ echo 'U2FsdGVkX194R0GmFKCL/krYCugS655yLhf8aQyKNcUnBs30AE5lHN5MXPjjSFML' | openssl enc -pass file:secret.key -d -aes-256-cbc -a string_to_encrypt 

5. الأمر grep


يجب أن يعلم الجميع قيادة grep. وتكون ودية مع التعبيرات العادية. وغالبًا ما يمكنك كتابة شيء مثل:

 tail -f application.log | grep -i error 

أو حتى مثل هذا:

 tail -f application.log | grep -i -P "(error|warning|failure)" 

لكن لا تنسى أن لدى grep الكثير من الخيارات الرائعة. على سبيل المثال -v ، يؤدي إلى إعادة البحث ويعرض جميع الرسائل باستثناء "المعلومات":

 tail -f application.log | grep -v -i "info" 

أشياء إضافية:

Option -P مفيد للغاية ، لأنه بشكل افتراضي يستخدم grep "تعبير عادي أساسي قديم": "، و -P يمكّن PCRE الذي لا يعرف حتى التجميع.
من أنا يتجاهل القضية.
- يوزع الخطوط المخزنة مؤقتاً على الفور بدلاً من الانتظار للوصول إلى المخزن المؤقت القياسي 4k (مفيد للذيل -f | grep)

إذا كنت تعرف التعبير المنتظم جيدًا ، فبواسطة - فقط - / -o يمكنك فعل أشياء رائعة من خلال قص النص. ما عليك سوى مقارنة الأمرين التاليين لاستخراج قشرة myuser:

 $ grep myuser /etc/passwd| cut -d ":" -f 7 $ grep -Po "^myuser(:.*){5}:\K.*" /etc/passwd 

يبدو الأمر الثاني أكثر تعقيدًا ، لكنه يعمل فقط على grep بدلاً من grep والمقطع ، لذلك سوف يستغرق وقتًا أقل للتنفيذ.

6. كيفية تقليل حجم ملف السجل


في * nix ، إذا قمت بحذف ملف السجل ، والذي يتم استخدامه حاليًا من قِبل أحد التطبيقات ، لا يمكنك فقط إزالة جميع السجلات ، يمكنك منع التطبيق من كتابة سجلات جديدة حتى يتم إعادة التشغيل.

لأن واصف الملف لا يفتح اسم الملف ، ولكن بنية iNode ، وسيستمر التطبيق في الكتابة إلى ملف واصف الملف ، والذي ليس له إدخال دليل ، وسيتم حذف هذا الملف تلقائيًا بعد توقف التطبيق بواسطة نظام الملفات ( يمكن للتطبيق الخاص بك فتح وإغلاق ملف السجل في كل مرة يريد فيها كتابة شيء لتجنب هذه المشكلة ، ولكنه يؤثر على الأداء ).

لذلك ، كيفية مسح ملف السجل دون حذفه:

 echo "" > application.log 

أو يمكننا استخدام أمر الاقتطاع:

 truncate --size=1M application.log 

أذكر ، سيحذف هذا الأمر المقتطع بقية الملف ، لذلك ستفقد آخر أحداث السجل. تحقق من مثال آخر حول كيفية تخزين آخر 1000 سطر:

 echo "$(tail -n 1000 application.log)" > application.log 

ملاحظة: في نظام Linux ، لدينا خدمة rotatelog قياسية. يمكنك إضافة سجلاتك إلى اقتطاع / تدوير تلقائي أو استخدام مكتبات السجل الحالية التي يمكنها القيام بذلك نيابة عنك (مثل log4j في java).

7. ووتش يراقب لك!


هناك موقف عندما تنتظر الانتهاء من بعض الأحداث. على سبيل المثال ، أثناء قيام مستخدم آخر بتسجيل الدخول إلى shell (يمكنك تنفيذ الأمر باستمرار) ، أو يجب أن يقوم شخص ما بنسخ الملف إلى جهازك باستخدام scp أو ftp وأنت في انتظار الإكمال (كرر عشرات المرات).

في مثل هذه الحالات ، يمكنك استخدام

 watch <command> 

افتراضيًا ، سيتم تنفيذ كل ثانيتين مع مسح الشاشة مسبقًا حتى يتم الضغط على Ctrl + C. يمكنك تكوين عدد مرات التنفيذ.

إنه مفيد للغاية عندما تريد مشاهدة السجلات المباشرة.

8. باش تسلسل


هناك بناء مفيد للغاية لإنشاء نطاقات. على سبيل المثال بدلاً من شيء مثل هذا:

 for srv in 1 2 3 4 5; do echo "server${srv}";done server1 server2 server3 server4 server5 

يمكنك كتابة ما يلي:

 for srv in server{1..5}; do echo "$srv";done server1 server2 server3 server4 server5 

كما يمكنك استخدام الأمر seq لإنشاء النطاقات المنسقة. على سبيل المثال ، يمكننا استخدام seq لإنشاء قيم سيتم ضبطها تلقائيًا حسب العرض (00 ، 01 بدلاً من 0 ، 1):

 for srv in $(seq -w 5 10); do echo "server${srv}";done server05 server06 server07 server08 server09 server10 

مثال آخر مع استبدال الأوامر - إعادة تسمية الملفات. للحصول على اسم ملف بدون امتداد ، نستخدم أمر " basename ":

 for file in *.txt; do name=$(basename "$file" .txt);mv $name{.txt,.lst}; done 

أيضًا أكثر اختصارًا مع '٪':

 for file in *.txt; do mv ${file%.txt}{.txt,.lst}; done 

ملاحظة: في الواقع ، لإعادة تسمية الملفات ، يمكنك تجربة أداة " إعادة تسمية " التي تحتوي على الكثير من الخيارات.

مثال آخر - يتيح إنشاء بنية لمشروع java جديد:

 mkdir -p project/src/{main,test}/{java,resources} 

نتيجة
 project/ !--- src/ |--- main/ | |-- java/ | !-- resources/ !--- test/ |-- java/ !-- resources/ 

9. الذيل ، ملفات متعددة ، العديد من المستخدمين ...


لقد ذكرت multitail لقراءة الملفات ومشاهدة سجلات حية متعددة. ولكنه لا يتم توفيره افتراضيًا ، وأذونات لتثبيت شيء غير متاح دائمًا.

لكن الذيل القياسي يمكن أن يفعل ذلك أيضًا:

 tail -f /var/logs/*.log 

يتيح لك أيضًا تذكر المستخدمين الذين يستخدمون الأسماء المستعارة "tail -f" لمشاهدة سجلات التطبيق.
يمكن للعديد من المستخدمين مشاهدة ملفات السجل في وقت واحد باستخدام "tail -f". البعض منهم ليست دقيقة جدا مع جلساتهم. يمكن أن يتركوا 'tail -f' في الخلفية لسبب ما وينسون الأمر.

إذا تم إعادة تشغيل التطبيق ، فهناك عمليات "tail -f" الجارية التي تشاهد ملف السجل غير الموجود يمكن تعليقها لعدة أيام أو حتى أشهر.

عادة ليست مشكلة كبيرة ، ولكنها ليست مشكلة بدقة.

في حالة ، إذا كنت تستخدم الاسم المستعار لمشاهدة السجل ، فيمكنك تعديل هذا الاسم المستعار باستخدام خيار --pid:

 alias TFapplog='tail -f --pid=$(cat /opt/app/tmp/app.pid) /opt/app/logs/app.log' 

في هذه الحالة ، سيتم إنهاء جميع المخلفات تلقائيًا عند إعادة تشغيل التطبيق الهدف.

10. إنشاء ملف بالحجم المحدد


كانت dd واحدة من أكثر الأدوات شعبية للعمل مع بيانات الكتلة والبيانات الثنائية. على سبيل المثال ، سيكون إنشاء ملف 1 ميغابايت مليئًا بصفر:

 dd if=/dev/zero of=out.txt bs=1M count=10 

لكنني أوصي باستخدام fallocate :

 fallocate -l 10M file.txt 

في أنظمة الملفات ، التي تدعم تخصيص وظيفة (xfs ، ext4 ، Btrfs ...) ، سيتم تنفيذ fallocate على الفور ، على عكس أداة dd. في تخصيص ، يعني التخصيص تخصيص حقيقي للكتل ، وليس إنشاء ملف احتياطي.

11. xargs


كثير من الناس يعرفون قيادة xargs شعبية. لكن ليس كلهم ​​يستخدمون خيارين التالية ، مما قد يؤدي إلى تحسين النص البرمجي بشكل كبير.

أولاً - يمكنك الحصول على قائمة طويلة جدًا من الوسائط لمعالجة ، ويمكن أن يتجاوز طول سطر الأوامر (افتراضياً ~ 4 كيلو بايت).

ولكن يمكنك تقييد التنفيذ باستخدام الخيار -n ، لذلك سيتم تشغيل أوامر xargs عدة مرات ، وإرسال عدد محدد من الوسائط في وقت واحد:

 $ # lets print 5 arguments and send them to echo with xargs: $ echo 1 2 3 4 5 | xargs echo 1 2 3 4 5 $ # now let's repeat, but limit argument processing by 3 per execution $ echo 1 2 3 4 5 | xargs -n 3 echo 1 2 3 4 5 

المضي قدما. قد تستغرق معالجة القائمة الطويلة الكثير من الوقت ، لأنها تعمل في خيط واحد. ولكن إذا كان لدينا العديد من النوى ، فيمكننا إخبار xargs بالتوازي:

 echo 1 2 3 4 5 6 7 8 9 10| xargs -n 2 -P 3 echo 

في المثال أعلاه ، نطلب من xargs معالجة القائمة في 3 سلاسل. سيستغرق كل مؤشر ترابط وسيطات 2 في التنفيذ. إذا كنت لا تعرف عدد النوى الموجودة لديك ، يتيح لك تحسين ذلك باستخدام " nproc ":

 echo 1 2 3 4 5 6 7 8 9 10 | xargs -n 2 -P $(nproc) echo 

12. النوم؟ في حين؟ قراءة!


بعض الوقت تحتاج إلى الانتظار لعدة ثوان. أو انتظر إدخال المستخدم مع قراءة:

 read -p "Press any key to continue " -n 1 

ولكن يمكنك فقط إضافة خيار مهلة لقراءة الأمر ، وسيتم إيقاف البرنامج النصي مؤقتًا لمدة محددة من الثواني ، ولكن في حالة التنفيذ التفاعلي ، يمكن للمستخدم تخطي الانتظار بسهولة.

 read -p "Press any key to continue (auto continue in 30 seconds) " -t 30 -n 1 

لذلك يمكنك فقط نسيان أمر النوم.

أظن أن الحيل ليست كلها مثيرة للاهتمام ، لكن يبدو لي أن هناك عددًا كبيرًا من الأرقام التي يجب ملؤها.

في هذا أقول وداعًا ، وسأكون ممتنًا للمشاركة في الاستبيان.

بالطبع لا تتردد في مناقشة ما ورد أعلاه ومشاركة الحيل الرائعة الخاصة بك في التعليقات!

Source: https://habr.com/ru/post/ar444890/


All Articles