Claude Code כקו-פקודה: סקריפטים, pipes ואוטומציה ב-CI
מאת צוות מדיה דיל · 08.08.2026 · AI · 9 דק׳
איך הופכים את Claude Code לכלי CLI אמיתי בנוסח יוניקס: piping של לוגים ו-diffs, הרצה עם -p ב-CI, ובניית סקריפטים שמריצים אותו בלי ממשק גרפי ובלי שאלות.
תארו לכם כלי פיתוח שיודע לקרוא לוג שגיאות שיצא מ-build שנכשל, להבין diff שלם של קוד, לכתוב הודעת commit, ולעשות את כל זה בלי לפתוח חלון אחד ובלי לשאול שאלה אחת. זה בדיוק מה ש-Claude Code עושה כשמריצים אותו במצב הלא-אינטראקטיבי שלו. מתחת לכל הפרומפטים והשיחות הנעימות ב-terminal מסתתר כלי CLI קלאסי בנוסח יוניקס - כזה שיודע לקבל קלט מ-stdin, להחזיר פלט מובנה ל-stdout, ולהשתלב בכל pipeline קיים בלי לדרוש שינוי בתשתית. במאמר הזה נצלול לתוך הדגל שהופך את זה לאפשרי - -p (או --print) - נראה דוגמאות אמיתיות של piping, ונבין איך לשלב את Claude Code בסקריפטים וב-CI/CD בלי לאבד שליטה על העלות והזמן.
פילוסופיית יוניקס, בקצרה - ולמה Claude Code מתאים לה
פילוסופיית יוניקס הישנה טוענת דבר פשוט: כלי טוב עושה דבר אחד, עושה אותו טוב, ומדבר בשפה משותפת עם כלים אחרים - טקסט רגיל שזורם דרך stdin ו-stdout. grep, sed, jq, git - כולם עובדים ככה, וזו הסיבה שאפשר לחבר אותם עם | (pipe) לשרשראות שמבצעות דברים מורכבים בלי שאף כלי בודד "יודע" יותר מדי.
Claude Code נבנה לפי אותה לוגיקה. ברירת המחדל שלו היא סשן אינטראקטיבי נעים בטרמינל, אבל מתחת לפני השטח הוא בעצם תוכנה שמקבלת קלט, מריצה agent loop, ומחזירה פלט - בדיוק כמו כל כלי CLI אחר. זה אומר שאפשר להזרים לתוכו קובץ לוג, diff של git, פלט של פקודה אחרת, ולקבל בחזרה טקסט, JSON, או stream של אירועים שממשיכים לרוץ הלאה בסקריפט. במקום "לפתוח את Claude ולשאול אותו", אפשר לכתוב שורה אחת בתוך package.json, ב-Makefile, או בשלב של GitHub Actions, שמריצה אותו כחלק משרשרת אוטומטית לגמרי. מי שרוצה רקע כללי על הכלי ועל אופן העבודה שלו יכול להתחיל ממדריך המבוא המלא ל-Claude Code לפני שצוללים לשכבת האוטומציה.
הדגל -p: מ-Claude אינטראקטיבי ל-headless
כשמריצים claude סתם, נפתח סשן אינטראקטיבי - אפשר לשוחח, לראות את Claude חושב, לאשר או לדחות פעולות בזמן אמת. אבל ברגע שמוסיפים את הדגל -p (או הצורה המלאה --print) לכל פקודת claude, ההתנהגות משתנה לגמרי: הכלי שולח את הבקשה, מריץ אותה עד הסוף, מדפיס את התשובה, ויוצא. אין תפריטים, אין המתנה לאישור ידני, אין session שנשאר פתוח - בדיוק ההתנהגות שסקריפט או שלב ב-CI צריכים.
הדוגמה הכי בסיסית היא שאלה ישירה: claude -p "מה עושה מודול האימות בפרויקט?" מדפיסה תשובה ויוצאת. חשוב לדעת: Claude Code יוצא עם קוד סיום 0 בהצלחה וקוד שונה מ-0 כשההרצה נכשלת, כך שסקריפט יכול להסתעף לפי סטטוס היציאה בדיוק כמו עם כל פקודת שורת פקודה אחרת. אם מעבירים דגל לא תקין, השגיאה מודפסת ל-stderr לפני שההרצה בכלל מתחילה; אם הכשל קורה בתוך ההרצה עצמה (למשל בעיית אימות), הוא מודפס כתוצאה ל-stdout.
לצורך עבודה ב-CI ובסקריפטים יש גם דגל --bare, שמדלג על גילוי אוטומטי של hooks, skills, plugins, שרתי MCP, זיכרון אוטומטי וקובצי CLAUDE.md. בלי הדגל הזה, claude -p טוען את אותו context שסשן אינטראקטיבי היה טוען - כולל כל מה שמוגדר בתיקיית העבודה או ב-~/.claude, מה שעלול לגרום להתנהגות שונה בין מכונה למכונה. במצב bare אין קריאה ל-OAuth או ל-keychain של המערכת, ולכן צריך להגדיר משתנה סביבה ANTHROPIC_API_KEY (מפתח שנוצר ב-Claude Console) כדי שההרצה תעבוד. בתיעוד הרשמי אף מצוין ש---bare הוא המצב המומלץ לקריאות מסקריפטים ומ-SDK, וצפוי להפוך לברירת המחדל של -p בעתיד.
pipe אמיתי: לוגים, diffs, ופלט מובנה
הלב של הגישה הזו הוא זרימת stdin. Claude Code קורא קלט שמוזרם אליו, כך שאפשר להעביר אליו כל דבר שאפשר להעביר לכל פקודת CLI אחרת - ולהפנות את הפלט שלו הלאה כרגיל.
דוגמה קלאסית: הזרמת לוג build שנכשל לניתוח, עם שמירת התוצאה לקובץ:
cat build-error.txt | claude -p 'הסבר בקצרה מה הגורם השורשי לשגיאת ה-build הזו' > output.txt
חשוב לשים לב למגבלה טכנית: קלט מוזרם ב-stdin מוגבל ל-10MB. אם חורגים מהמגבלה, Claude Code יוצא עם שגיאה ברורה וקוד יציאה שונה מ-0. לקבצים גדולים יותר, עדיף לכתוב את התוכן לקובץ ולהפנות את Claude Code לנתיב הקובץ בתוך הפרומפט, במקום להזרים אותו ישירות.
דוגמה שנייה, שימושית מאוד לבדיקות קוד: הזרמת diff של git ישירות ל-Claude, בלי לתת לו הרשאת Bash בכלל - כי הוא מקבל את התוכן דרך ה-pipe ולא צריך להריץ פקודות בעצמו:
- git diff main | claude -p "את/ה linter של שגיאות כתיב. עבור כל שגיאה ב-diff, דווח filename:line בשורה אחת ואת הבעיה בשורה הבאה. אל תחזיר שום דבר נוסף."
דוגמה כזו אפשר להטמיע ישירות כסקריפט בתוך package.json, למשל תחת "lint:claude", ואז להריץ עם npm run lint:claude. שימו לב שמרכאות כפולות בתוך הפרומפט צריך "לברוח" (escape) כדי שהסקריפט יישאר תקין גם בסביבת Windows.
לשליטה בפורמט הפלט יש את הדגל --output-format עם שלוש אפשרויות: text (ברירת המחדל, פלט טקסט רגיל), json (מבנה JSON מלא הכולל את התשובה תחת השדה result, מזהה session, ומטא-דאטה - כולל total_cost_usd ופירוט עלות לפי מודל, כך שאפשר לעקוב אחרי הוצאה של כל הרצה בלי לפתוח דשבורד), ו-stream-json - פלט של JSON מופרד בשורות, שמאפשר קבלת אירועים בזמן אמת, כולל אירוע result אחרון עם התשובה הסופית, העלות ומטא-דאטה של הסשן. עם --json-schema אפשר גם לקבל פלט מובנה שמאומת מול סכימת JSON Schema - למשל לחלץ מערך של שמות פונקציות מתוך קובץ.
כדי לעבד את הפלט אפשר להיעזר ב-jq: claude -p "סכם את הפרויקט הזה" --output-format json | jq -r '.result' מוציא רק את הטקסט, ואפשר גם לסנן אירועי stream-json כדי להציג טקסט זורם בזמן אמת מתוך שידור ה-tokens.
הרצה ב-CI/CD - בלי להישבר ובלי הפתעות
כדי להריץ את Claude Code בצינור CI צריך שתי אבני יסוד: אימות שלא תלוי בהתחברות אינטראקטיבית, ושליטה על מה מותר לו לעשות. לאימות ב-CI יש פקודה ייעודית - claude setup-token - שיוצרת טוקן OAuth ארוך טווח מיועד לסביבות אוטומטיות, לצד האפשרות הפשוטה יותר של הגדרת ANTHROPIC_API_KEY בסביבה.
לשליטה על הרשאות יש כמה שכבות. --allowedTools מאשר מראש כלים ספציפיים בלי לבקש אישור בזמן ריצה, למשל --allowedTools "Bash,Read,Edit", ואפשר לצמצם עוד יותר לפי תבנית פקודה מדויקת בעזרת syntax של כללי הרשאה - כמו Bash(git diff *) שמאשר רק פקודות שמתחילות ב-git diff (הרווח לפני ה-* חשוב, אחרת גם git diff-index ייכנס בטעות לתבנית). לחלופין, --permission-mode קובע קו בסיס לכל הסשן: acceptEdits מאפשר לכתוב קבצים ולהריץ פקודות מערכת קבצים נפוצות כמו mkdir או mv בלי לשאול, ו-dontAsk שימושי דווקא ל-CI נעול - הוא דוחה כל דבר שלא מופיע במפורש בכללי ה-allow, כך שההרצה נכשלת בבירור במקום להיתקע בהמתנה לאישור שלעולם לא יגיע.
לניהול סיכונים יש גם רשתות ביטחון מובנות: --max-turns מגביל את מספר הצעדים האגנטיים שהרצה אחת יכולה לבצע, ו---max-budget-usd עוצר את ההרצה כשהיא חוצה תקציב כספי מוגדר - שני דגלים קריטיים כשמריצים את הכלי אוטומטית וללא השגחה אנושית צמודה. חשוב גם לדעת שאם Claude מפעיל תהליך רקע (כמו dev server) בזמן הרצת -p, התהליך מסתיים כחמש שניות אחרי שהתוצאה הסופית חזרה - כך שהרצה לא נשארת תקועה עם תהליכים פתוחים.
בפועל, שילוב טבעי הוא בתוך GitHub Actions או GitLab CI: שלב בפייפליין שמזרים diff של pull request, מריץ עליו בדיקה עם -p ו---output-format json, ומחליט לפי הפלט (או לפי קוד היציאה) האם לחסום merge, להוסיף תגית, או לכתוב תגובה אוטומטית. למי שכבר בונה אינטגרציות CI/CD מסודרות עם GitHub, כדאי להצליב את זה עם המדריך שלנו לאוטומציה עם GitHub API ו-CI/CD, ולזכור שגם skills ו-custom commands עובדים בתוך -p - פשוט כותבים /שם-הפקודה בתוך מחרוזת הפרומפט, כפי שהרחבנו במדריך ה-skills וה-commands.
תרחיש שימוש: reviewer אוטומטי לבדיקת אבטחה ב-PR
הנה דוגמה שממחישה איך כל החלקים מתחברים לכלי עבודה אמיתי. שומרים סקריפט קטן, לדוגמה בשם review.sh, שמושך diff של pull request ב-GitHub ומזרים אותו ל-Claude Code עם system prompt מותאם:
gh pr diff "$1" | claude -p --append-system-prompt "את/ה מהנדס/ת אבטחה. סקור/י לפגיעויות אבטחה." --output-format json
הפרמטר "$1" מייצג את הארגומנט הראשון שמעבירים לסקריפט - כך שהרצה של bash review.sh 123 מביאה בפועל את ה-diff של PR מספר 123. הפלט חוזר כ-JSON עם הביקורת בתוך שדה result, ומכאן קצרה הדרך לחלץ אותו עם jq ולפרסם כתגובה אוטומטית על ה-PR, לתעד אותו בלוג, או לשלוח אותו כהתראה בערוץ צוות. אותו דפוס בדיוק - Bash אחד, pipe אחד, שורת claude -p - מתאים גם לתרגום קובצי תיעוד, גם ליצירת commit message מתוך git diff מצוין, וגם לריצה מתוזמנת שסורקת לוגים של production ומזקקת מהם דוח יומי קריא. זה בדיוק החוזק של גישת יוניקס: אותו אבן בניין אחת, מורכבת מחדש לכל תרחיש.
שאלות נפוצות
מה בדיוק ההבדל בין claude רגיל ל-claude -p?
claude ללא דגלים פותח סשן אינטראקטיבי בטרמינל, עם שיחה מתמשכת ואישורים בזמן אמת. claude -p (או --print) שולח בקשה, מריץ אותה עד הסוף בלי לשאול, מדפיס תשובה, ויוצא - בדיוק ההתנהגות שמתאימה לסקריפטים ול-CI, כי אין שם אף אחד שילחץ Enter על אישור.
יש הגבלת גודל על מה שמזרימים ל-Claude Code דרך stdin?
כן - קלט מוזרם דרך stdin מוגבל ל-10MB, ומעבר לזה ההרצה נכשלת עם שגיאה ברורה וקוד יציאה שונה מ-0. לקבצים גדולים יותר עדיף לשמור את התוכן לקובץ ולהפנות את Claude Code לנתיב הקובץ בתוך הפרומפט, במקום להזרים אותו ישירות דרך pipe.
איך שולטים בעלות כשמריצים את הכלי אוטומטית, בלי השגחה?
שני דגלים מיועדים בדיוק לזה: --max-turns מגביל כמה צעדים אגנטיים הרצה בודדת יכולה לבצע, ו---max-budget-usd עוצר את ההרצה כשהיא חוצה תקציב כספי מוגדר מראש. בנוסף, פלט מסוג --output-format json כולל שדה total_cost_usd ופירוט עלות לפי מודל בכל הרצה, כך שאפשר לעקוב אחרי הוצאה גם בדיעבד.
אפשר להמשיך שיחה קודמת גם במצב headless?
כן. --continue ממשיך את השיחה האחרונה, ו---resume עם מזהה session ממשיך שיחה ספציפית. דפוס נפוץ הוא לשמור את מזהה ה-session מהרצה ראשונה עם --output-format json ולחלץ אותו עם jq, ואז להעביר אותו ל---resume בהרצות הבאות - כולל מתיקיות עבודה אחרות באותה מכונה.
מה ההבדל בין --output-format json ל-stream-json?
json מחזיר מבנה שלם אחד בסוף ההרצה - עם התשובה, מזהה session ומטא-דאטה. stream-json מחזיר אירועי JSON מופרדים בשורות תוך כדי ריצה, כולל טוקנים של הטקסט בזמן אמת כשמוסיפים גם --verbose ו---include-partial-messages, כשהאירוע האחרון בסטרים הוא תוצאה סופית עם הטקסט המלא, העלות ומטא-דאטה של הסשן.
צריך התחברות אינטראקטיבית כדי להריץ את Claude Code ב-CI?
לא. אפשר להגדיר משתנה סביבה ANTHROPIC_API_KEY עם מפתח מ-Claude Console, או ליצור טוקן ייעודי ל-CI עם הפקודה claude setup-token. בשילוב עם --bare, ההרצה מדלגת גם על קריאת OAuth credentials וה-keychain של המערכת, ומתנהגת אותו הדבר בכל מכונה שמריצה אותה.
אם אתם בונים pipeline שבו Claude Code צריך לקרוא לוגים, לסקור diffs, או לרוץ אוטומטית כחלק מ-CI - זה בדיוק סוג העבודה שאנחנו עושים אצל לקוחות כל הזמן, החל מהגדרת הדגלים הנכונים ועד חיבור מלא ל-GitHub Actions. מוזמנים לדבר איתנו בוואטסאפ
תגיות: Claude Code CLI · claude -p · headless mode · אוטומציה CI/CD · piping לינוקס · Claude Code סקריפטים · GitHub Actions Claude