Przekaż parametr do zadania sieci szkieletowej

123

Jak mogę przekazać parametr do zadania sieci szkieletowej, wywołując „fab” z wiersza poleceń? Na przykład:

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

Done.

Czy można to zrobić bez pytania fabric.operations.prompt?

Donovan
źródło

Odpowiedzi:

207

Dokumentacja argumentów zadań Fabric 2:

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


Fabric 1.X używa następującej składni do przekazywania argumentów do zadań:

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

Możesz przeczytać więcej na ten temat w dokumentacji Fabric .

Jakub Roztocil
źródło
9
Cytaty nie są konieczne; wszystkie argumenty są ciągami: „ponieważ ten proces obejmuje analizę ciągów, wszystkie wartości zostaną przekształcone w łańcuchy języka Python, więc zaplanuj odpowiednio. (Mamy nadzieję ulepszyć to w przyszłych wersjach Fabric, pod warunkiem, że można znaleźć intuicyjną składnię).”
Carl G
4
Czy cytaty wokół hello worldwydają się konieczne?
PEZ
2
@PEZ Jeśli to prawda, cudzysłowy są prawdopodobnie potrzebne w tym przykładzie, ponieważ parser wiersza poleceń terminala lub sieci szkieletowej zobaczy spację i pomyśli, że to koniec wszystkiego dla tego zadania, a to worldbyło nowe zadanie.
Adam Kerz
1
Ponadto po użyciu tego przez mniej niż minutę odkryłem, że w systemie Windows używanie pojedynczych cudzysłowów powoduje, że pojedyncze cudzysłowy są przekazywane jako część argumentu, ale podwójne cudzysłowy są najpierw usuwane. Tak więc, 'hello world'dałoby w Pythonie ciąg znaków 'hello world', ale "hello world"skutkowałby hello world(co prawdopodobnie jest tym, czego większość ludzi chciałaby).
Adam Kerz
5
Ponieważ proces obejmuje parsowanie ciągów, bar=Truew materiale zostanie przekazane polecenie, bar='True'które nie jest wartością logiczną
Programator chemiczny
7

Argumenty dotyczące tkaniny są zrozumiałe przy bardzo podstawowym przetwarzaniu ciągów, więc musisz zachować ostrożność przy ich wysyłaniu.

Oto kilka przykładów różnych sposobów przekazywania argumentów do następującej funkcji testowej:

@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'})

Używam tutaj podwójnego cudzysłowu, aby usunąć powłokę z równania, ale pojedyncze cudzysłowy mogą być lepsze na niektórych platformach. Zwróć także uwagę na ucieczki znaków, które tkanina uważa za ograniczniki.

Więcej szczegółów w dokumentach: http://docs.fabfile.org/en/1.14/usage/fab.html#per-task-arguments

Bogdan Kiselitsa
źródło
7

W Fabric 2 po prostu dodaj argument do funkcji zadania. Na przykład, aby przekazać versionargument do zadania deploy:

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

Uruchom go w następujący sposób:

fab -H host deploy --version v1.2.3

Tkanina nawet automatycznie dokumentuje opcje:

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

Docstring:
  none

Options:
  -v STRING, --version=STRING
mrts
źródło
czy istnieje sposób na predefiniowanie hostów w samej funkcji? Podobnie jak w tagu @roles (), w którym możemy zdefiniować listę hostów do uruchomienia zadania.
Anish
2

Musisz przekazać wszystkie zmienne Pythona jako ciągi znaków, zwłaszcza jeśli używasz podprocesu do uruchamiania skryptów, w przeciwnym razie wystąpi błąd. Będziesz musiał osobno przekonwertować zmienne z powrotem na typy 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'
frage
źródło
1

Jeśli ktoś chce przekazać parametry z jednego zadania do drugiego w fabric2, po prostu użyj do tego słownika środowiska:

@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')

I biegnij:

fab2 qa sign
MikeL
źródło