GNU Makefiles'de proses ikamesi


11

Bir bash isteminde, sözde dosyaları kullanarak diff yürütülebilir:

diff <(echo test) <(echo test)

Bunu bir Makefile'a olduğu gibi eklemek başarısız olur:

all:
        diff <(echo test) <(echo test)

Hata (ipucu: / bin / sh bu sistemdeki / bin / bash öğesini gösterir):

/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'

Bu ne anlama geliyor ve geçici dosyaları kullanmadan iki çıktıyı dağıtmanın bir yolu var mı?

Yanıtlar:


20

/bin/sholabilir bashsisteminizde, ancak çağrıldığında sh, bash(sanki POSIX modunda çalışıyor olacak POSIXLY_CORRECTtanımlandı veya onunla başladı --posix).

Bu modda, işlem ikameleri mevcut değildir.

Çözümler:

all:
    command1 >file1
    command2 >file2
    diff file1 file2
    rm -f file1 file2

Alternatif:

all:
    bash -c "diff <(command1) <(command2)"

Veya sadece Makefile değişkenini SHELLşu şekilde tanımlayın /bin/bash:

SHELL=/bin/bash

Taşınabilirlik istiyorsanız, ilk çözümle devam edin. Bağımlılığı olan bir sorun yoksa bash, ikincisini seçin. Ek olarak GNU dışı makeuygulamaları önemsemeniz gerekmiyorsa , üçüncüyü kullanın.


Ayarla ilgili olarak SHELL: POSIX standardı, Makefiles içindeki yürütülebilir dosyaların system()C kütüphanesi işleviyle çağrılması gerektiğini söylüyor make. Bu işlevin SHELLortam değişkenini kullanacağı garanti edilmez (aslında bunu yapmak standart tarafından önerilmez). Standart, Makefile değişkeninin ayarlanmasının ortam değişkeniniSHELL etkilememesi gerektiğini söylemek için de bir miktar uzar . Ancak bildiğim çoğu uygulamada , komutları yürütmek için Makefile değişkeni kullanılacaktır. SHELLmakeSHELL

İçinde öneri Rationale için makeyardımcı kullanım için bash -c:

Tarihsel MAKESHELLözellik ve diğer makeuygulamalar tarafından sağlanan ilgili özellikler atlanmıştır. Bazı uygulamalarda, bir kullanıcının makekomutları çalıştırmak için kullanılacak kabuğun üzerine yazmasına izin vermek için kullanılır . Bu kafa karıştırıcıydı; bir taşınabilir için make, kabuk makefile yazar tarafından seçilmelidir. Ayrıca, bir makefile yazarı alternatif bir kabuğun kullanılmasını gerektiremez ve hala makefile taşınabilir olarak düşünülebilir. Alternatif bir kabuk belirtmek için bir mekanizmayı standartlaştırmak mümkün olsa da, mevcut uygulamalar böyle bir mekanizma üzerinde anlaşmaya varmaz ve makefile yazarları bir hedef kuralında kabuk adını belirterek alternatif bir kabuk çağırabilir; Örneğin:

python -c "foo"


bashGeçici dosyalar kullanmadan Makefile veya diff sorununa başka bir çözüm çağırmanın bir yolu var mı ?
Johannes

Sadece iki geçici dosya kullanın, bu işlem değiştirme yönteminin zaten kaputun altında yapacağı şeydir.
Kusalananda

3
Ayrıca ayarlayabilirsiniz SHELLiçin /bin/bashMakefiledaki.
Stephen Kitt

1
@Johannes Kusalananda, cevabına bilgiyi ekledi, bu da bir dizi seçenek ve kullanılabilecek koşullar sunduğu için harika. Bu cevabı kabul etmeyi tercih ederim ... (Ama duyguyu takdir ediyorum!)
Stephen Kitt

2
SHELL değişkenini kullanmanın POSIX uyumlu olmadığı bilgisi çok yardımcı oldu. Belki de kullanmak daha iyidir bash -c.
Johannes
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.