ส่งผ่านพารามิเตอร์ไปยังงานแฟบริค


123

ฉันจะส่งผ่านพารามิเตอร์ไปยังงานแฟบริคได้อย่างไรเมื่อเรียก "fab" จากบรรทัดคำสั่ง ตัวอย่างเช่น:

def task(something=''):
    print "You said %s" % something
$ fab task "hello"
You said hello

Done.

เป็นไปได้ไหมที่จะทำสิ่งนี้โดยไม่ต้องแจ้งด้วยfabric.operations.prompt?

คำตอบ:


207

เอกสารประกอบอาร์กิวเมนต์งาน Fabric 2:

http://docs.pyinvoke.org/en/latest/concepts/invoking-tasks.html#task-command-line-arguments


Fabric 1.X ใช้ไวยากรณ์ต่อไปนี้สำหรับการส่งผ่านอาร์กิวเมนต์ไปยังงาน:

 fab task:'hello world'
 fab task:something='hello'
 fab task:foo=99,bar=True
 fab task:foo,bar

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับมันในเอกสารผ้า


9
คำพูดไม่จำเป็น อาร์กิวเมนต์ทั้งหมดเป็นสตริง: "เนื่องจากกระบวนการนี้เกี่ยวข้องกับการแยกวิเคราะห์สตริงค่าทั้งหมดจะลงเอยด้วยสตริง Python ดังนั้นควรวางแผนให้เหมาะสม (เราหวังว่าจะปรับปรุงสิ่งนี้ใน Fabric เวอร์ชันต่อ ๆ ไปหากพบไวยากรณ์ที่ใช้งานง่าย)"
Carl G

4
คำพูดรอบ ๆhello worldดูเหมือนจำเป็นหรือไม่?
PEZ

2
@PEZ หากเป็นเช่นนั้นคำพูดอาจจำเป็นในตัวอย่างนั้นเนื่องจากตัวแยกวิเคราะห์บรรทัดคำสั่งของเทอร์มินัลหรือแฟบริคจะเห็นช่องว่างและคิดว่านั่นคือจุดสิ้นสุดของทุกอย่างสำหรับงานนั้นและนั่นworldเป็นงานใหม่
Adam Kerz

1
นอกจากนี้หลังจากใช้สิ่งนี้ไม่ถึงหนึ่งนาทีฉันพบว่าใน Windows การใช้เครื่องหมายคำพูดเดี่ยวส่งผลให้เครื่องหมายคำพูดเดี่ยวถูกส่งเป็นส่วนหนึ่งของอาร์กิวเมนต์ แต่เครื่องหมายคำพูดคู่จะถูกตัดออกก่อน ดังนั้น'hello world'จะส่งผลให้เกิดสตริง Python 'hello world'แต่"hello world"จะส่งผลhello world(ซึ่งอาจเป็นสิ่งที่คนส่วนใหญ่ต้องการ)
Adam Kerz

5
เนื่องจากกระบวนการเกี่ยวข้องกับการแยกวิเคราะห์สตริงbar=Trueในคำสั่ง fabric จะส่งผ่านbar='True'ซึ่งไม่ใช่ค่าบูลีน
Chemical Programmer

7

อาร์กิวเมนต์ Fabric เข้าใจได้ด้วยการแยกวิเคราะห์สตริงขั้นพื้นฐานดังนั้นคุณต้องระมัดระวังเล็กน้อยเกี่ยวกับวิธีการส่ง

นี่คือตัวอย่างบางส่วนของวิธีต่างๆในการส่งผ่านอาร์กิวเมนต์ไปยังฟังก์ชันทดสอบต่อไปนี้:

@task
def test(*args, **kwargs):
    print("args:", args)
    print("named args:", kwargs)

$ fab "test:hello world"
('args:', ('hello world',))
('named args:', {})

$ fab "test:hello,world"
('args:', ('hello', 'world'))
('named args:', {})

$ fab "test:message=hello world"
('args:', ())
('named args:', {'message': 'hello world'})

$ fab "test:message=message \= hello\, world"
('args:', ())
('named args:', {'message': 'message = hello, world'})

ฉันใช้เครื่องหมายคำพูดคู่ที่นี่เพื่อนำเปลือกออกจากสมการ แต่อัญประกาศเดี่ยวอาจดีกว่าสำหรับบางแพลตฟอร์ม นอกจากนี้โปรดสังเกตการ Escape สำหรับอักขระที่ Fabric พิจารณาตัวคั่น

รายละเอียดเพิ่มเติมในเอกสาร: http://docs.fabfile.org/en/1.14/usage/fab.html#per-task-arguments


7

ใน Fabric 2 เพียงเพิ่มอาร์กิวเมนต์ให้กับฟังก์ชันงานของคุณ ตัวอย่างเช่นการส่งผ่านversionอาร์กิวเมนต์ไปยังงานdeploy:

@task
def deploy(context, version):
    ...

เรียกใช้ดังนี้:

fab -H host deploy --version v1.2.3

Fabric แม้กระทั่งเอกสารตัวเลือกต่างๆโดยอัตโนมัติ:

$ fab --help deploy
Usage: fab [--core-opts] deploy [--options] [other tasks here ...]

Docstring:
  none

Options:
  -v STRING, --version=STRING

มีวิธีกำหนดโฮสต์ล่วงหน้าในฟังก์ชันหรือไม่ คล้ายกับแท็ก @roles () ที่เราสามารถกำหนดรายชื่อโฮสต์เพื่อเรียกใช้งานได้
Anish

2

คุณต้องส่งผ่านตัวแปร Python ทั้งหมดเป็นสตริงโดยเฉพาะอย่างยิ่งหากคุณใช้กระบวนการย่อยเพื่อรันสคริปต์ไม่เช่นนั้นคุณจะได้รับข้อผิดพลาด คุณจะต้องแปลงตัวแปรกลับเป็นประเภท int / boolean แยกกัน

def print_this(var):
    print str(var)

fab print_this:'hello world'
fab print_this='hello'
fab print_this:'99'
fab print_this='True'

1

หากมีคนต้องการส่งผ่านพารามิเตอร์จากงานหนึ่งไปยังอีกงานหนึ่งใน fabric2 ให้ใช้พจนานุกรมสภาพแวดล้อมสำหรับสิ่งนั้น:

@task
def qa(ctx):
  ctx.config.run.env['counter'] = 22
  ctx.config.run.env['conn'] = Connection('qa_host')

@task
def sign(ctx):
  print(ctx.config.run.env['counter'])
  conn = ctx.config.run.env['conn']
  conn.run('touch mike_was_here.txt')

และเรียกใช้:

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