הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

מדריך sed

משמעות השם sed היא Stream Editor, ותפקידו של sed בהתאם: הוא עורך טקסט שמקבל את הקלט שלו בתור זרם (מקובץ או מ Pipeline) ועורך את הטקסט שמגיע לפי הוראות שהעברנו מראש. במדריך זה אספר על סד, קודם התיאוריה ואז דרך דוגמאות.

המשך קריאה

מדריך awk

הכלי awk היה לאורך שנים ועודנו אחד הכלים המרכזיים לעיבוד טקסט בסביבת יוניקס. הוא פותח בשנות ה 70 בחברת Bell Labs על ידי שלושה מפתחים ששמותיהם נתנו לכלי את שמו: Alfred Aho, Peter Weinberger ו Brian Kernighan. הייחודיות של awk היא שמצד אחד הוא כולל אלמנטים מתקדמים משפות תכנות כמו משתנים, מערכים, מילונים ואפילו אפשרות להגדיר פונקציות; אבל מצד שני זה כלי סקריפטים שהשימוש בו מאוד ממוקד לפיענוח טקסטים.

היכרות עם awk תאפשר לנו להעלות את הרמה של הסקריפטים שאנחנו כותבים וגם לפתור בעיות הקשורות לטקסט במהירות ומשורת הפקודה.

המשך קריאה

היום למדתי: הפניית פלט לכמה קבצים ב zsh

לפעמים יתרונות קטנים מתגלים לאט. ל zsh עברתי כבר לפני כמה שנים כי אפל החליטו שזה shell ברירת מחדל טוב יותר ואף פעם לא היה לי אכפת במיוחד כי כל הטריקים שהכרתי מ bash עבדו טוב גם בו. והשמחה האמיתית היא להתחיל לגלות טריקים חדשים.

אנחנו כבר יודעים להשתמש ב tee כדי לכתוב בפקודה אחת לכמה קבצים:

$ echo hello world | tee a b c d >& /dev/null

וזה עובד גם ב bash וגם ב zsh. אבל מסתבר שב zsh יש עוד טריק איתו אפשר לוותר על tee:

$ { echo hello world } > a > b > c > d

וזה יוצר ארבעה קבצים שנקראים a, b, c ו d בהתאמה ובתוך כל אחד מהם כותב את הטקסט hello world.

מיטיבי לכת יכולים לוותר גם על כל החצים ולהשתמש בשתי נקודות כששמות הקבצים מתאימים. במקרה שלנו:

$ { echo hello world } > {a..d}

נ.ב. את הפקודה המרכזית אני מקיף בסוגריים מסולסלים כי אחרת zsh לא תמיד יודע שהיא נגמרה. הסבר מדויק אפשר למצוא בתיעוד שלהם כאן: https://zsh.sourceforge.io/Doc/Release/Redirection.html#Multios

איך ליצור Lambda Function ו API Gateway על AWS באמצעות ה CLI

אחד הטרנדים החמים היום בפיתוח הוא Serverless או פיתוח ללא קוד Back End, או יותר נכון פיתוח בלי מערכת Back End מלאה שמטפלת בכל ההיבטים של צד השרת. פיתוח Serverless יהיה יותר דומה לפיתוח Micro Services, אבל בצורה שכל סרביס רץ בתוך סביבת ריצה מנוהלת ומבוקרת משלו.

שירות AWS Lambda הוא דוגמה לפיתוח מסוג זה. הוא מאפשר לנו לכתוב קוד (פונקציה) שירוץ בכל פעם שקורה משהו ויחזיר תוצאה למי שקרא לו. באמצעות חיבור הפונקציה לשירות שנקרא API Gateway אנחנו הופכים את אותה פונקציה לזמינה מכל מקום ברשת למרות שהיא עצמה בסך הכל פונקציה קטנה אחת ולא מערכת Back End מלאה.

במדריך זה אראה איך להקים פונקציה (לא משהו מסובך היא רק תחזיר Hello World בדוגמה שלנו) ולחבר אותה ל API Gateway וכל זה באמצעות שימוש בכלי שורת הפקודה של AWS בלבד.

המשך קריאה

איך להריץ סקריפט כל פעם שהלפטופ מתחבר או מתנתק מהחשמל ב Ubuntu

מאז שעברתי ללינוקס גיליתי שזמן הסוללה של הלפטופ תלוי בהמון המון דברים ושאפשר עם שינויים קטנים לקבל הרבה יותר שעות מחשב גם כשאין חשמל בסביבה. צריך רק לזכור להפסיק את הגיבוי, להוריד את בהירות המסך, להאט קצת את המעבד, לבטל תהליכי רקע מיותרים ולקוות לטוב. אומנם Ubuntu לא יעשה בשבילכם יותר מדי בגיזרת שימור חיי הסוללה אבל קל מאוד (אם יודעים איפה לחפש) להוסיף סקריפטים שלנו שיקראו כל פעם שהמחשב מתחבר או מתנתק מהחשמל והם כבר יטפלו בסגירת תהליכים זוללי סוללה.

בשביל להריץ סקריפטים בעת חיבור או ניתוק מהחשמל נצטרך להתקין את החבילה pm-utils וגם לעדכן מספר הגדרות. נתחיל בהתקנה:

$ sudo apt-get install pm-utils

חבילת pm-utils כוללת שתי פקודות מעניינות. הראשונה מכניסה אותנו למצב חיסכון בחשמל:

sudo pm-powersave true

והשניה חוזרת למצב עבודה רגיל:

sudo pm-powersave false

פקודות אלה מחפשות סקריפטים בתוך תיקיית /etc/pm/power.d ויריצו את כל הסקריפטים שם לפי סדר, כשכל סקריפט מופעל עם הפרמטר true או false (הפרמטר true מציין כניסה למצב חיסכון בחשמל, false מציין יציאה ממצב זה).

עד לפה הכל טוב ויפה אבל רובנו לא הולכים לזכור כל פעם שאנחנו מנתקים את המחשב מהחשמל גם להריץ את הסקריפט של pm-powersave ולכן צריך עוד שינוי קטן כדי שמנגנון זה ירוץ אוטומטית בעת ניתוק או חיבור המחשב לחשמל. אחרי חיפוש קצר ברשת מצאתי שדרך קלה לעשות את זה היא להוסיף udev rule. בתור מנהל מערכת ניצור את הקובץ /etc/udev/rules.d/99-powersave.rules ובתוכו נכתוב:

SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/usr/sbin/pm-powersave true"
SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/usr/sbin/pm-powersave false"

לאחר מכן הפעילו את הפקודה הבאה כדי לרענן את כללי ה udev:

udevadm control --reload-rules && udevadm trigger

וצרו את הסקריפטים שאתם צריכים בתיקיית /etc/pm/power.d. כל סקריפט שתיצרו שם יופעל אוטומטית כשהמערכת נכנסת למצב חיסכון בחשמל או יוצאת ממנו. בדף התיעוד על ניהול צריכת חשמל תוכלו למצוא דוגמאות לסקריפטים כאלה וכלים שיעזרו לכם לצמצם את צריכת החשמל של המחשב כשהוא לא מחובר לקיר.

איך להפוך את Caps Lock ל Escape ב Linux

מסיבות היסטוריות מוזרות כל יצרני המקלדות מתעקשים לשים כפתור חסר ערך לחלוטין במקום טוב בשורה האמצעית ולזרוק את הכפתור הכי חשוב במקלדת לפינה השמאלית עליונה. לשמחתנו זו טעות שמאוד קל לתקן בתוכנה וב Linux אפשר למצוא שלוש גישות מרכזיות לתיקון:

המשך קריאה

כמה טיפים מדליקים לשימוש בפקודה date

הפקודה date היא האולר השוויצרי של המרות תאריכים. היא תעזור לנו להשתתף בכנסים ואירועי תרבות מכל העולם (כי תמיד נוכל לזהות באיזה שעה הם מתקיימים בשעון המקומי שלנו) ולבצע חישובים עם זמנים בלי לעזוב את שורת הפקודה. הנה כמה מהשימושים שאני אוהב ל date:

המשך קריאה

הדרך הכי טובה להתעלם מתיקיה או קובץ עם find

הפקודה find היא אחת הפקודות הגמישות ביותר של יוניקס והיא יודעת למצוא קבצים לפי כל פרמטר שאפשר לדמיין. הרבה זמן תהיתי למה אין אף מתג שמאפשר ל find לדלג על ספריות בדומה ל --exclude של grep. את התשובה מצאתי אחרי שהבנתי איך find עובד, והיא הרבה יותר פשוטה ממה שאתם מדמיינים.

אז בואו ניזכר רגע בהפעלה פשוטה של find למשל בשביל למצוא קבצים שהשם שלהם הוא package.json:

$ find . -type f -name package.json

הפקודה find מקבלת רצף של קריטריונים לחיפוש ובונה מהם שרשרת תנאים. במקביל היא רצה על כל הקבצים והתיקיות החל מתיקיית ההתחלה שלה ומעבירה כל נתיב בשרשרת התנאים שמצאה. במקרה שלנו למשל שרשרת התנאים היא:

  1. אנחנו מחפשים קובץ
  2. השם חייב להיות package.json

כש find מוצא נתיב למשל demo.txt קודם כל הוא בודק מה סוג הדבר שיש שם. בואו נניח ש demo.txt הוא קובץ אז הוא יעבור את החוליה הראשונה וייפול בשניה.

שרשראות תנאים יכולות גם להתפצל, למשל ה find הבא שמשתמש ב or יזהה קבצים בשם package.json או תיקיות בשם node_modules:

$ find . \( -type f -name package.json \) -or \( -type d -name node_modules \)

והנה עלינו לשתי שרשראות: או שעברת את כל השרשרת הראשונה, או שעברת את כל השרשרת השניה. כל שרשרת מורכבת משני תנאים.

עכשיו הגיע הזמן לשאול מה קורה עם הנתיב אחרי שהשרשרת נגמרת? באופן רגיל נתיב שסיים את כל השרשרת פשוט יודפס, אבל find נותנת לנו לשחק גם עם התנהגות זו. הפרמטר --exec הוא דוגמא לפקודה שמסיימת את השרשרת, באמצעות הרצת פקודה על הקובץ שנמצא. זאת הסיבה שהשורה הבאה תמחק לכם קובץ בשם demo.txt למרות שאתם חושבים שאתם מדברים על תיקיה:

$ find . -name 'one.txt' -exec ls -l {} \; -type d

הבעיה היא שיצרנו שרשרת שמסתיימת ב exec ובזה הסיפור שלנו נגמר. הפקודה -type d היא חסרת משמעות כאן כי היא באה אחרי סוף השרשרת.

ואם הבנתם את כל זה אתם מוכנים לשמוע את התשובה מתחילת הפוסט: משביל לדלג על קבצים או תיקיות ב find, כל מה שצריך זה לדאוג שהם לא יעברו את השרשרת. כך הפקודה הבאה תציג את כל הקבצים שמתחילים ב o ומסתיימים ב txt מלבד one.txt:

$ find . -type f -not -name 'one.txt' -name 'o*.txt'

ואם רוצים להתעלם מתיקיות הפקודה prune גורמת ל find לסיים את השרשרת ולדלג על התיקיה (היא רלוונטית רק כשהנתיב הוא תיקיה). לכן הפקודה הבאה תחפש את הקובץ package.json בכל מקום מלבד בתוך תיקיית node_modules:

$ find . -type d -name node_modules -prune -false -or -name package.json

ברירת המחדל של -prune היא להדפיס את התיקיה עליה היא דילגה, והתוספת -false מיד אחריה מדלגת על אותה הדפסה. בלי זה נקבל בפלט גם את התיקיה node_modules עליה דילגנו.

על ההבדל הקטן ב Bash בין printf ל echo

במשחקים עם דוקר ראיתי את השורה הבאה בתיעוד שלהם:

$ printf "This is a secret" | docker secret create my_secret_data -

זה דווקא טריק נחמד - הוא אומר שיש לנו תוכנית שמצפה לקבל את הקלט שלה ל STDIN אבל מצד שני אנחנו רוצים להעביר לתוכנית טקסט קבוע. במקום להדפיס את הטקסט לקובץ ולתת לתוכנית לקרוא מהקובץ, אנחנו מדפיסים את הטקסט ישירות באמצעות Pipe ל STDIN של התוכנית.

זה עובד גם מחוץ לדוקר, למשל התוכנית wc יודעת די טוב לספור תווים בשורה שהיא קוראת מתוך STDIN או מקובץ, אבל אם יש לכם ביד טקסט קבוע תוכלו להשתמש ב printf כדי לשלוח אותו ישירות אליה:

$ printf "hello world" | wc -c
11

אז למה printf ולא echo? כי מסתבר ש echo מוסיף תו ירידת שורה לטקסט אותו הוא מדפיס. כך בספירת התווים אנחנו מקבלים:

$ echo "hello world" | wc -c

לכן בדוגמא של דוקר נבחרה הפקודה printf. אם נוסיף תו ירידת שורה שם תו זה יישמר בתור חלק מה Secret ועלול לפגוע בהתנהגות של תוכניות שצריכות את המידע.

נ.ב.1 אז נכון יש דרכים לגרום ל echo לוותר על תו ירידת השורה אבל בכל מערכת יוניקס הדרך היא קצת שונה ויש גם מקומות ש echo לא יקשיב לכם, לא משנה כמה תבקשו.

נ.ב.2 דרך התמודדות אחרת שעוקפת את הבעיה היא למחוק את הרווחים ותווי ירידת השורה כשקוראים Secret בתוכנית שרצה בתוך קונטיינר. אני מעדיף ליישם את שתי השיטות כלומר לשמור את הסוד בלי תו ירידת השורה ולכתוב את התוכנית כך שתהיה מספיק חכמה להתעלם מתווי ירידת שורה ורווחים שאולי נכנסו בטעות.