นักเทียบท่าเรียกใช้ <IMAGE> <คำสั่งหลายรายการ>


255

ฉันพยายามเรียกใช้คำสั่ง MULTIPLE เช่นนี้

docker run image cd /path/to/somewhere && python a.py

แต่สิ่งนี้ทำให้ฉัน "ไม่มีไฟล์หรือไดเรกทอรี" ข้อผิดพลาดเพราะมันถูกตีความว่าเป็น ...

"docker run image cd /path/to/somewhere" && "python a.py"

ดูเหมือนว่าจำเป็นต้องใช้อักขระ ESCAPE บางตัวเช่น "" หรือ ()

ดังนั้นฉันก็ลอง

docker run image "cd /path/to/somewhere && python a.py"
docker run image (cd /path/to/somewhere && python a.py)

แต่สิ่งเหล่านี้ใช้ไม่ได้

ฉันค้นหาDocker Run Reference แล้วแต่ไม่พบคำแนะนำใด ๆ เกี่ยวกับตัวละคร ESCAPE

คำตอบ:


440

ในการรันหลายคำสั่งในตัวเทียบท่าใช้/bin/bash -cและอัฒภาค;

docker run image_name /bin/bash -c "cd /path/to/somewhere; python a.py"

ในกรณีที่เราต้องการ command2 (python) จะถูกดำเนินการถ้าหาก command1 (cd) คืนสถานะศูนย์ (ไม่มีข้อผิดพลาด) ให้ใช้&&แทน;

docker run image_name /bin/bash -c "cd /path/to/somewhere && python a.py"

ขอบคุณสำหรับคำใบ้! ฉันลอง [นักเทียบท่าเรียกใช้อิมเมจ "cd / bin; ls"] และได้รับข้อความแสดงข้อผิดพลาดดังต่อไปนี้ [exec: "cd / bin; ls": stat cd / bin; ls: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว] [การตอบสนองข้อผิดพลาดจาก daemon: ไม่สามารถเริ่มต้นคอนเทนเนอร์]
ai0307

1
ใครก็ตามที่พบคำตอบนี้อาจสนใจวิธีใช้เอกสารที่นี่เพื่อฟีดคำสั่งไปยังคอนเทนเนอร์: นี่คือคำตอบของฉันสำหรับคำถามอื่นเกี่ยวกับที่นี่เอกสารนี้โปรดอย่าลังเลที่จะตรวจสอบ
KohányiRóbert

14
docker run alpine sh -c "ls | wc >> xxx"ช่วยฉันได้มากเมื่อไม่สามารถใช้ bash ได้
Eddy Hernandez

1
ใช้งานcdได้ แต่ไม่ใช่สำหรับสิ่งที่รหัสส่งคืนมีความสำคัญ;ไม่เหมือน&&ดูunix.stackexchange.com/questions/37069/ …
Nick Zalutskiy

1
ขอบคุณ @NickZalutskiy อัพเดตคำตอบพร้อมกับความคิดเห็นของคุณแล้ว
anhlc

31

คุณสามารถทำได้สองวิธี:

  1. ใช้ตัวเลือก -w เพื่อเปลี่ยนไดเรกทอรีการทำงาน:

    -w, --workdir = "" ไดเรกทอรีทำงานภายในคอนเทนเนอร์

    https://docs.docker.com/engine/reference/commandline/run/#set-working-directory--w

  2. ส่งผ่านอาร์กิวเมนต์ทั้งหมดไปที่ / bin / bash:

    docker run image /bin/bash -c "cd /path/to/somewhere; python a.py"
    

ไม่มีการกล่าวถึง--workdirในลิงก์ที่ให้ไว้ หน้าอาจมีการย้าย / เปลี่ยนแปลง สามารถอัปเดตเป็นdocs.docker.com/engine/reference/run/#workdirหรือdocs.docker.com/engine/reference/commandline/run
marcv

10

คุณยังสามารถไพพ์คำสั่งภายในคอนเทนเนอร์ Docker ได้bash -c "<command1> | <command2>"เช่น:

docker run img /bin/bash -c "ls -1 | wc -l"

แต่ถ้าไม่มีการเรียกใช้เชลล์ในรีโมตเอาต์พุตจะถูกเปลี่ยนทิศทางไปยังโลคัลเทอร์มินัล


3

หากคุณต้องการเก็บผลลัพธ์ไว้ในไฟล์เดียวนอกคอนเทนเนอร์ในเครื่องของคุณคุณสามารถทำสิ่งนี้ได้

RES_FILE=$(readlink -f /tmp/result.txt)

docker run --rm -v ${RES_FILE}:/result.txt img bash -c "cat /etc/passwd | grep root > /result.txt"

ผลลัพธ์ของคำสั่งของคุณจะพร้อมใช้งานใน/tmp/result.txtเครื่องท้องถิ่นของคุณ


2

สำหรับคนอื่นที่มาที่นี่มองหาที่จะทำเช่นเดียวกันกับdocker-composeคุณเพียงแค่ต้องย่อหน้าbash -cและใส่คำสั่งหลายในเครื่องหมายคำพูด, &&ร่วมกันกับ

ดังนั้นในตัวอย่าง OPs docker-compose run image bash -c "cd /path/to/somewhere && python a.py"


อันนี้ใช้ได้สำหรับฉัน แต่กระบวนการตัวเทียบท่าออกหลังจากรันคำสั่งแล้ว
node_man

และฉันจะออกจากกระบวนการเทียบท่าได้อย่างไร การกด ctrl C หรือ ctrl Z หรือการพิมพ์ exit ไม่ทำงานหรือฉันต้องฆ่ามันโดยคำสั่ง docker stop?
node_man

ไม่docker-compose down [service-name]ได้ทำงานหรือ? (และไม่ต้องกังวลคุณยินดีให้ความช่วยเหลือ :))
S.

2

เพียงเพื่อให้คำตอบที่เหมาะสมจากความคิดเห็นของ @Eddy Hernandez และถูกต้องมากเนื่องจากอัลไพน์มาพร้อมกับเถ้าไม่ทุบตี

คำถามนี้ referes ที่จะเริ่มต้นเปลือกในภาชนะเทียบท่าอัลไพน์ซึ่งหมายถึงการใช้shหรือashหรือหรือ/bin/sh/bin/ash/

ตามคำถามของ OP:

docker run image sh -c "cd /path/to/somewhere && python a.py"


1

bash -cทำงานได้ดีถ้าคำสั่งที่คุณใช้นั้นค่อนข้างง่าย อย่างไรก็ตามหากคุณพยายามเรียกใช้ชุดคำสั่งที่มีความยาวเต็มไปด้วยอักขระควบคุมมันอาจซับซ้อน

ฉันประสบความสำเร็จในการแก้ไขปัญหานี้โดยการส่งคำสั่งไปยังกระบวนการจากภายนอกคือ

cat script.sh | docker run -i <image> /bin/bash

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.