Skip to content

Coreutils מקומיים ב־Windows: כלים מעשיים לפיתוח חוצה פלטפורמות והמגבלות שלהם

מעבר בין מעטפות דמויות Unix ל־Windows יכול לשבש הרגלים מוכרים בשורת הפקודה. cmd.exe הקלאסית אינה מספקת כברירת מחדל את ls -la. גם התקנת כלים חיצוניים אינה הופכת סקריפט Bash לסקריפט PowerShell; ‏grep, ‏awk ו־sed הם כלים נפרדים עם דרישות התקנה משלהם.

Git Bash, ‏Cygwin ו־WSL מציעים דרכים שונות להשתמש בכלים דמויי Unix ב־Windows. ‏WSL 2 משתמש במכונה וירטואלית מנוהלת; WSL 1 אינו משתמש בה. כאן נתמקד ב־uutils/coreutils, מימוש מחדש של GNU Coreutils ב־Rust עם גרסאות Windows מקומיות. כלים משותפים יכולים לצמצם חיכוך, אך אינם הופכים לבדם כל סקריפט לנייד.

הדילמה של המפתחים: החיכוך בין מערכות הפעלה

צוותים עשויים לפרוס ל־Linux בזמן שהמפתחים עובדים ב־Windows או ב־macOS. אוטומציה משותפת צריכה להתחשב בסביבות השונות, ולא להניח שאותה מערכת הפעלה נמצאת בכל מקום.

כך נוצרת נקודת חיכוך משמעותית. נניח שאתם כותבים סקריפט עזר לפרויקט — למשל, סקריפט שמנתח קובץ תצורת JSON מקומי, מחלץ ממנו ערך ומייצר תוצר בנייה. איך תכתבו אותו?

  • אפשרות א׳: Bash. השתמשו בסביבה תואמת Bash בכל תחנת עבודה נתמכת, ובדקו את הטיפול בנתיבים.
  • אפשרות ב׳: PowerShell ‏(pwsh). היא חוצת פלטפורמות, אך העצמים והתחביר שלה שונים מצינורות פקודות של Unix; חברי הצוות זקוקים לסביבת הריצה המתאימה.
  • אפשרות ג׳: סקריפטים ב־Node.js או ב־Python. אפשר לכתוב בהם לוגיקה ניידת, אך עדיין צריך לבדוק התנהגות של מערכת הקבצים ושל תהליכי משנה בפלטפורמות השונות.

Coreutils כוללת כלים מוכרים כגון cat, ‏cut, ‏head, ‏tail ו־wc. היא אינה כוללת grep, ‏find או xargs; ‏uutils מפתחת אותם בפרויקטים נפרדים. לא כל כלי Unix או תכונה זמינים בכל חבילת Windows, ולכן יש לבדוק את החבילה שנבחרה.

הכירו את uutils: השכתוב המודרני ב־Rust

uutils/coreutils היא כתיבה מחדש פעילה וחוצת פלטפורמות של GNU Coreutils ב־Rust. זהו מימוש נפרד, ולא רק הידור של קוד GNU ל־Windows.

הפרויקט כתוב ב־Rust ותומך בהרצה מקומית ב־Windows. תאימות GNU היא יעד, אך האפשרויות וההתנהגות עשויות להיות שונות. גרסאות מקומיות אינן דורשות מכונת Linux וירטואלית; העובדה הזאת ושפת המימוש אינן מוכיחות יתרון ביצועים גורף.

מתי כדאי להשוות בין כלים מקומיים ל־WSL

WSL 2 מריץ ליבת Linux במכונה וירטואלית מנוהלת. גישה בין מערכות הקבצים של Windows ו־Linux עלולה לעלות בביצועים; Microsoft ממליצה לשמור את קובצי הפרויקט במערכת ההפעלה שמריצה את הכלים. הרשת של WSL יכולה להשתמש ב־NAT או בשיקוף, ולכן תיאור של כתובת IP נפרדת אינו נכון תמיד.

כשעובדים על קבצים בכונן Windows, השוו כלים מקומיים לתצורת WSL שלכם באמצעות נתונים מייצגים. המאמר אינו מספק מדידות זמן. חיפוש באמצעות grep דורש גם התקנת grep נפרדת, ולא רק coreutils.

הגדרת Coreutils מקומיים ב־Windows

הפרויקט מתעד חבילות Windows דרך Winget ו־Scoop, וכן התקנה באמצעות Cargo. השתמשו בהוראות העדכניות לגרסה ולארכיטקטורה שנבחרו. הפקודות הבאות הן דוגמאות לעיון, ולא פקודות שהורצו לצורך המאמר.

שיטה 1: התקנה באמצעות Cargo — מומלץ למפתחי Rust

כאשר שרשרת כלי Rust הנדרשת זמינה, הפרויקט מתעד את פקודת Cargo הבאה עבור Windows:

cargo install coreutils --features windows --locked

שיטה 2: התקנה באמצעות Scoop

למי שמשתמשים ב־Scoop, כלי ההתקנה קל המשקל לשורת הפקודה ב־Windows, זה פשוט במיוחד:

scoop bucket add main
scoop install uutils-coreutils

שמות קובצי ההפעלה תלויים בחבילה ובארכיטקטורה. מניפסט Scoop שנבדק חושף שמות רגילים כגון ls.exe ו־cat.exe, ולא קידומת אחידה של uutils-. בדקו כיצד שמות פקודות נפתרים לפני הוספת מיפויים או שינוי PATH.

תרחישים מהשטח: צינורות פקודות של Unix ב־Windows

הדוגמאות הבאות כתובות ל־PowerShell ב־Windows, כאשר קובצי ההפעלה הנקובים מותקנים. הן מדגימות את ההבדל בין כלים חיצוניים דמויי Unix לתכונות המעטפת. הן לא הורצו כאן.

1. סינון יומנים בזמן אמת: tail בשילוב PowerShell

ב־PowerShell אפשר לעקוב אחר קובץ באמצעות Get-Content -Wait. אם מעדיפים tail מקומי, אפשר להפעיל במפורש את tail.exe ולהשתמש ב־Select-String של PowerShell לסינון שאינו מבחין בין אותיות גדולות לקטנות:

tail.exe -f .\development.log | Select-String -Pattern "error"

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

2. ניתוח מהיר של נפח תיקיות בדיסק (du)

לגבי תיקיות משנה בתוך node_modules, תנו ל־PowerShell למנות את הנתיבים במפורש. תחילה בדקו כיצד נפתרים השמות du.exe ו־sort.exe. גם Windows מספקת sort.exe שאינו מקבל את דגל GNU ‏-h; סיומת בלבד אינה בוחרת את uutils. לפני הרצה החליפו את נתיבי ההמחשה שלהלן בנתיבים המלאים והמאומתים של קובצי uutils שבחרתם.

Get-Command du.exe -All
Get-Command sort.exe -All
# Replace BOTH placeholders with verified paths to the intended uutils executables.
$duExe = 'C:\REPLACE_WITH_VERIFIED_UUTILS_DIRECTORY\du.exe'
$sortExe = 'C:\REPLACE_WITH_VERIFIED_UUTILS_DIRECTORY\sort.exe'
Get-ChildItem -LiteralPath .\node_modules -Directory |
    ForEach-Object { & $duExe -sh -- $_.FullName } |
    & $sortExe -h

להלן שורות נפח להמחשה בלבד; אלה אינן תוצאות שנמדדו בהתקנת Windows, ועיצוב הנתיבים יהיה שונה מהנתיבים המלאים המפורשים שבפקודה למעלה:

1.2M    ./node_modules/lodash
4.8M    ./node_modules/typescript
12M     ./node_modules/webpack
...

3. תצוגה מקדימה של שינוי סיומות בקבצים רבים

צינור פקודות שמוסיף .jpg אינו מחליף את .jpeg, והוא גם עלול להתנגש בקובצי יעד קיימים. התחילו בתצוגה מקדימה של השמות המוצעים. דוגמת PowerShell הזאת רק מציגה נתיבי מקור ויעד; היא אינה משנה שמות ואינה ממירה את נתוני התמונה. בדקו התנגשויות וגיבויים לפני כל שינוי בהמשך.

Get-ChildItem -LiteralPath . -Filter '*.jpeg' -File -Recurse |
    ForEach-Object {
        [pscustomobject]@{
            Source = $_.FullName
            ProposedName = [IO.Path]::ChangeExtension($_.FullName, '.jpg')
        }
    }

טיפול בהתנגשות הכינויים של PowerShell

ב־PowerShell נפוצים כינויים כגון ls עבור Get-ChildItem ו־echo עבור Write-Output. ‏Windows Terminal הוא יישום מסוף עם פרופילי מעטפת הניתנים להגדרה; הוא אינו מגדיר את משמעות הפקודות האלה.

הכינויים האלה נועדו להקל על המעבר של משתמשי Unix, אבל הם אינם תומכים בדגלים של GNU. אם תנסו להריץ ls -la ב־PowerShell מקומית, תקבלו שגיאה מפני ש־Get-ChildItem אינה מכירה את הפרמטרים -la.

לפני עריכת פרופיל, בדקו את פתרון שמות הפקודות. סיומת של קובץ הפעלה או נתיב מלא יכולים לעקוף כינוי, בתנאי שקובץ ההפעלה שנבחר מותקן. הדוגמאות האלה אינן משנות את הפרופיל:

Get-Command ls -All
Get-Command ls.exe -All
# Run only after verifying that this is the intended uutils executable.
ls.exe -la

בחירה מפורשת מונעת סוג אחד של התנגשות שמות. היא אינה הופכת את PowerShell לתואמת POSIX ואינה מבטיחה התנהגות GNU בכל פלטפורמה. אם מספר קובצי הפעלה חולקים שם, השתמשו בנתיב המלא שאומת.

ההשפעה על CI/CD ועל תהליכי העבודה בצוות

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

בסקריפטים של package.json ובקובצי Makefile, ציינו את המעטפת, גרסאות הכלים, פתרון שמות קובצי ההפעלה וכללי הנתיבים הנתמכים. כללי ציטוט ותווים כלליים עדיין שונים. בדקו כל סביבת Windows, ‏macOS ו־Linux נתמכת ואת סביבת ה־CI לפני שטוענים שהסקריפט פועל באופן זהה.

סיכום וקריאה לפעולה

כלי uutils מקומיים יכולים להוסיף פעולות קבצים וטקסט מסוימות בסגנון Unix לתהליך עבודה ב־Windows. הם משלימים את PowerShell, סביבות Bash או WSL, ולא מחליפים אותן אוטומטית. בחרו את השילוב שמתאים לעומס העבודה שלכם ובדקו את התנהגותו.

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


איך נראית סביבת המסוף המקומית שלכם? אתם עדיין מסתמכים על WSL לפעולות קבצים בסיסיות, או שכבר עברתם לכלי שורת פקודה מקומיים וחוצי פלטפורמות? בואו נדבר על כך בתגובות, או שתשתפו אותי בקיצורי הדרך האהובים עליכם לשיפור העבודה במסוף ב־Twitter/X, אצל @sysseder!

מקורות ראשוניים לתיקונים

Post a Comment

Previous Post Next Post