عيون حمراء





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



ربما لاحظ كل من عمل في وحدة التحكم في بعض أنظمة Linux الميزة الملائمة لعرض المجلد الحالي واسم المستخدم واسم الخادم وشيء آخر اعتمادًا على التوزيعات في سطر المطالبة. لطالما أحببت ذلك أيضًا. لكن في بعض الأحيان اتضح الأمر







على النحو التالي : من الصعب "الإنشاء" في سطر مكون من ثلاثة أحرف ، وبالطبع يتحرك المؤشر إلى السطر التالي ، لكنه بالأحرى يثير حنق أكثر مما يساعد. وفي وقت ما ، قلت لنفسي:







قررت استعادة مساحة سطر الأوامر بالكامل وعدم إعطائها لأي شخص مرة أخرى. كان السؤال كيف يتم تغيير نص موجه الأوامر؟ اتضح أنه بسيط للغاية ، ما عليك سوى تغيير متغير النظام الخاص "PS1".







نعم ، يمكنك تعيين نص دعوة جديد مباشرة في المحطة. لكن كيف تحفظ التغييرات؟ وحتى بدون معلومات عن الكتالوج الحالي ، فإنك تشعر بطريقة ما بعدم الارتياح ، وتسأل نفسك باستمرار السؤال: "أين أنا؟" سيساعد ملف ~ / .bashrc ، حيث يمكنك حفظ تغيير PS1 ، وبالتالي لا تشغل المعلومات حول الدليل الحالي مساحة العمل ، قررت عدم وضعه في سطر الأوامر ، ولكن فوق سطر الأوامر. أضف السطر التالي إلى ملف ~ / .bashrc :



PS1='$PWD\n# '


انتبه إلى علامات الاقتباس الفردية ، إذا استخدمنا علامات الاقتباس المزدوجة ، فبدلاً من المؤشر إلى المتغير $ PWD ( متغير نظام يخزن المسار الكامل للمجلد الحالي ، مشابه لأمر pwd) ، ستتم كتابة قيمته (الدليل الحالي) إلى سلسلة المطالبة وتغييرها عند الانتقال من المجلد لن يكون المجلد. يبدو الأمر كما يلي:







سطر الأوامر مجاني تمامًا ، لكن اسم المجلد يندمج مع المحتويات إذا قمت بتشغيل الأمر ls . سيتعين علينا فصل الذباب عن المقتطفات ، واسم المجلد من المحتويات. قررت إضافة "إطارات" لـ $ PWD بإضافة خطوط "-" في الأعلى والأسفل. كيف تعرف عدد الأحرف في السطر؟ هناك أيضًا متغير النظام $ COLUMNS لهذا الغرض.... ولتكوين سلسلة بسرعة بالعدد المطلوب من الأحرف "-" ، استخدم الأمر printf :



printf -v line "%${COLUMNS}s"


سيقوم هذا الأمر بإنشاء سطر $ متغير وملئه بمسافات بقيمة $ COLUMNS لكننا لسنا بحاجة إلى مسافات ولكن "-" ، لهذا نستخدم الحيلة التالية:



line=${line// /-} #     -


دعونا نضيف هذا الرمز إلى ~ / .bashrc



printf -v line "%${COLUMNS}s"
line=${line// /-}
PS1='\n$line\n$PWD\n$line\n# '






رائع ، لكن إذا قمنا بتغيير حجم النافذة الطرفية الآن ، فلن يتغير حجم "الخطوط" وسيختفي الجمال:







لتصحيح الموقف ، سننقل الكود الجديد إلى وظيفة المعلومات ونضيفه إلى PS1:



info () {
    printf -v line "%${COLUMNS}s"
    line=${line// /-}
    printf "\n$line\n$PWD\n$line\n# "
}
PS1='$(info)'


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



info () {
    name_length="{ $HOSTNAME }"
    name_length=${#name_length}
    top_line_left=$[(COLUMNS-name_length)/2]
    top_line_right=$[COLUMNS-(top_line_left+name_length)]
    printf -v top_line "%${top_line_left}s{_S_${HOSTNAME}_S_}%${top_line_right}s"
    printf -v bot_line "%${COLUMNS}s"
    bot_line=${bot_line// /-}
    top_line=${top_line// /-}
    top_line=${top_line//_S_/ }
    printf "\n$top_line\n$PWD\n$bot_line\n# "
}
PS1='$(info)'






لقد أرفقت اسم المضيف بأقواس معقوفة بمسافات ، ولكن بدلاً من المسافات حول $ HOSTNAME ، يتم استخدام الأحرف "_S_" ، والتي يتم تغييرها بعد ذلك إلى مسافات. يعد هذا ضروريًا لأنه يتم استبدال جميع المسافات في السطر الأخير بـ "-" ، ويجب أن تظل المسافات داخل الإدخال. دعنا نضيف الألوان ، لهذا سنقوم بإعداد متغيرات برموز لتغيير لون النص في المحطة ، لقد استخدمت الألوان التالية:



RED='\e[31m' # 
GRN='\e[32m' # 
YLW='\e[33m' # 
BLU='\e[34m' # 
MGN='\e[35m' # 
DEF='\e[0m'  #    
BLD='\e[1m'  # 
DIM='\e[2m'  # 


دعنا نضيف هذه المتغيرات إلى الكود الخاص بنا:



info () {
    name_length="{ $HOSTNAME }"
    name_length=${#name_length}
    top_line_left=$[(COLUMNS-name_length)/2]
    top_line_right=$[COLUMNS-(top_line_left+name_length)]
    printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME${DEF}_S_$GRN}%${top_line_right}s"
    printf -v bot_line "%${COLUMNS}s"
    bot_line=$GRN${bot_line// /-}$DEF
    top_line=${top_line// /-}
    top_line=$GRN${top_line//_S_/ }$DEF
    printf "\n$top_line\n$BLD$BLU$PWD$DEF\n$bot_line\n# "
}
PS1='$(info)'






تفضل ، يبدو الجانب الأيمن فارغًا ، يمكنك وضع التاريخ والوقت هناك:



printf -v date "%(%a %d %b %T)T"


لوضع هذا على اليمين ، تحتاج إلى إضافة بعض المسافات بعد $ PWD ، والتي ، دعنا نحسبها:



center_space=$[COLUMNS-${#date}-${#PWD}]
((center_space<0)) && center_space=1
...
printf "\n$top_line\n$BLD$BLU$PWD$DEF%${center_space}s$DIM$date\n$bot_line\n# "






هل يمكنك فعل ما هو أفضل؟ بالطبع ، دعنا نضيف ناتج حالة git إذا كنا في المجلد مع مشروع git :



    git_tst= git_clr=
    [[ -d .git ]] && {
        git_tst=($(git status -c color.ui=never -sb))
        git_tst="GIT ${git_tst[*]} " #   
        git_clr=(GIT $(git -c color.ui=always status -sb))
        git_clr="GIT ${git_clr[*]} " #   
    }
    ...
    center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}]
    ...
    printf "\n$top_line\n$BLD$BLU$PWD$DEF%${center_space}s$git_clr$DIM$date\n$bot_line\n\$ "






لاحظ أنه يتم كتابة git_clr و git_tst أولاً كمصفوفة ثم تحويلها إلى متغيرات. يعد هذا ضروريًا لإزالة فواصل الأسطر من إخراج حالة git . لكن أين العيون؟ الآن سيكون هناك عيون O_o ، فلنقم بإنشاء مصفوفة بمجموعة أساسية من العيون:



eyes=(O o ∘ ◦ ⍤ ⍥)


ودعنا نحسب عددهم:



en=${#eyes[@]}


دعنا نضيف رمز الفم:



mouth='_'


ودعنا نصنع منشئ الوجوه العشوائية:



face () {
    printf "$YLW${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}$DEF"
}


ستكون العيون موجودة عند أطراف حقل المعلومات ، يجب أن تأخذها في الاعتبار عند حساب عدد المسافات في المنتصف ، سنقوم بإعداد متغير منفصل لهذا:



face_tst='O_o  o_O'
...
center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}-${#face_tst}]
printf "\n$top_line\n$(face) $BLD$BLU$PWD$DEF%${center_space}s$git_clr$DIM$date $(face)\n$bot_line\n\$ "






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



info () {
    error=$?
    ...
}


ودعنا نغير وظيفة الوجه بحيث تتحقق من متغير الخطأ $ ، واعتمادًا على قيمتها ، نرسم العينين باللون الأحمر أو الأصفر:



face () {
    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW
    printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"
}






حسنًا ، تحولت عيني إلى اللون الأحمر ، لكن يمكنك إضافة شيء آخر. لنقم بإضافة شيك للمتغير debian_chroot $ :



[[ $debian_chroot ]] && chrt="($debian_chroot)" || chrt=
...
name_length="{ $HOSTNAME$chrt }"
...
printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME$chrt${DEF}_S_$GRN}%${top_line_right}s"


ودعنا نغير النص الموجود في عنوان النافذة الطرفية:



PS1='$(info)'; case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;$(face 1) \w\a\]$PS1";; esac


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



face () {
    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW
    [[ $1 ]] && printf "${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}" \
             || printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"
}






النص النهائي:



RED='\e[31m' # 
GRN='\e[32m' # 
YLW='\e[33m' # 
BLU='\e[34m' # 
MGN='\e[35m' # 
DEF='\e[0m'  #    
BLD='\e[1m'  # 
DIM='\e[2m'  # 
eyes=(O o ∘ ◦ ⍤ ⍥) en=${#eyes[@]} mouth='_'
face () {
    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW
    [[ $1 ]] && printf "${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}" \
             || printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"
}
info () { error=$? git_tst= git_clr=
    [[ -d .git ]] && {
        git_tst=($(git -c color.ui=never status -sb))
        git_tst="GIT ${git_tst[*]} " #   
        git_clr=($(git -c color.ui=always status -sb))
        git_clr="GIT ${git_clr[*]} " #   
    }
    [[ $debian_chroot ]] && chrt="($debian_chroot)" || chrt=
    name_length="{ $HOSTNAME$chrt }"
    name_length=${#name_length}
    face_tst='O_o  o_O'
    top_line_left=$[(COLUMNS-name_length)/2]
    top_line_right=$[COLUMNS-(top_line_left+name_length)]
    printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME$chrt${DEF}_S_$GRN}%${top_line_right}s"
    printf -v bot_line "%${COLUMNS}s"
    printf -v date  "%(%a %d %b %T)T"
    top_line=${top_line// /-}
    top_line=$GRN${top_line//_S_/ }$DEF
    bot_line=$GRN${bot_line// /-}$DEF
    center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}-${#face_tst}]
    ((center_space<0)) && center_space=1
    printf "\n$top_line\n$(face) $BLD$BLU$PWD$DEF%${center_space}s$git_clr$DIM$date $(face)\n$bot_line\n\$ "
}
PS1='$(info)'; case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;$(face 1) \w\a\]$PS1";; esac


هذا كل شيء ، شكرًا لاهتمامكم!) اشترك ، مثل ، هذا كل شيء ، المشروع موجود في شريط المعلومات github أنشئ ، اخترع ، جرب!)



فحص الرعاية
"#" "$"?)



(*) (*)



All Articles