Запуск скриптовых команд в make-файле (Linux make)

602
Simon H

Я боролся с этим большую часть прошлой ночи.

Я хочу, чтобы переименовать все файлы xxxx-yyyyв xxxx:yyyyв папке из Makefile.

У меня есть, renamefiles.shкоторый делает работу хорошо:

#!/bin/sh for i in $i do echo $i echo mv "$" "$"; mv "$" "$"; done 

Но я бы очень хотел поместить это в make-файл.

Makefile из OpenWRT / Lede; фрагмент, где он должен быть:

define Build/Prepare $(Build/Prepare/Default) tar xvfj $(DL_DIR)/$(PKG_DATA_FILENAME) -C $(PKG_BUILD_DIR) rm -f \ $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/05c6:1000:sVe=GT cp ./data/* $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/  ./renamefiles.sh $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/ endef 

Так что я бы очень хотел, в make-файле, переименовать $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/????-????в????:????

но что бы я ни пытался, я, похоже, получил какую-то ошибку (обычно unexpected end of fileот bash?).

Я также ищу решение, которое будет работать без дополнительных предпосылок; Например, мое первое исследование показало, что renameоно хорошо справилось бы с этой задачей, но я был предупрежден, потому что оно доступно не везде.

0
1) действительно ли `for i in $ i` настоящая копия / вставка? не должно ли быть `для меня в $ *`? 2) вызов makefile должен быть `./renamefiles.sh $ (PKG_BUILD_DIR) / $ (PKG_DATA_PATH) /usb_modeswitch.d / ???? - ????` Archemar 7 лет назад 1
Также рассмотрите возможность использования команды `rename` (упакованной во многих дистрибутивах) с регулярным выражением в стиле perl вместо домашнего сценария. dirkt 7 лет назад 0
@dirkt - см. ниже. «переименовать» был мой первый выбор :). Simon H 7 лет назад 0
@Archemar - да, было уже поздно, и я уже удалил большую часть своей тестовой работы! спасибо за выделение ...; Simon H 7 лет назад 0

1 ответ на вопрос

1
Simon H

вместо того, чтобы редактировать мой собственный вопрос; Я думал, что отвечу на это, поэтому вопрос есть, чтобы обратиться.

Да, скрипт тоже не работал ....

«рабочий» скрипт выглядит следующим образом:

#!/bin/bash shopt -s nullglob for i in $1*-* do echo file is $i FILENAME=$(basename $i) echo filename is $FILENAME NEWNAME=$ echo newname is $NEWNAME rm "$1$NEWNAME" mv "$1$FILENAME" "$1$NEWNAME" done 

так; поправки:

  1. 1 доллар после.

  2. подстановка в имени файла отличается в #! / bin / sh и #! / bin / bash - в основном $ не работает в MY #! / bin / sh .... (обратите внимание на $ - две косые черты означают «замените КАЖДЫЙ xyz на abc, один означает, что первый xyz будет заменен на abc. Также обратите внимание, что дефис МОЖЕТ быть экранирован, поскольку он может указывать индикатор диапазона).

  3. добавьте 'shopt -s nullglob' перед циклом for, иначе, если НЕТ подходящих файлов, вы получите шаблон поиска в виде файла ....

  4. делать смещение только на имя файла, так как путь содержит много дефисных каталогов!

использование 'переименовать' - не было разрешено сопровождающим проекта :(.

Теперь о том, чтобы поместить его в make-файл.

  1. Моя первоначальная проблема заключалась в том, что я не смог пройти «bash - неожиданный конец файла». На самом деле все просто - все ДОЛЖНО быть эффективно в одной строке. конец строки с (пробел); (пробел) \, чтобы заставить bash использовать ';' в качестве маркера конца строки, и используйте '\', чтобы указать, что вы хотите, чтобы все, что было представлено, было в одной строке.

  2. Использование $. Я читал во многих местах, что в make-файлах, если вы использовали $ для прохода через bash, то вам пришлось использовать два (то есть $$ FILENAME). Но мне пришлось использовать ЧЕТЫРЕ ($$$$ FILENAME). Все, что я могу предположить в этой точке, это то, что в сложной системе buildroot Lede / Openwrt, make-файлы каким-то образом включают в себя включения, включаются включения, и я нашел только 4 экспериментально. Я не видел этого ни в одном другом ответе на вопросы о циклах в make-файлах :).

итак, финальный фрагмент make-файла: (обратите внимание на снимок, чтобы он работал, даже если файлы не найдены)

shopt -s nullglob ; \ for filevar in $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/*-* ; \ do \ echo file is $$$$filevar ; \ FILENAME=$$$$(basename $$$$filevar) ; \ echo filename is $$$$FILENAME ; \ NEWNAME=$$$$ ; \ echo newname is $$$$NEWNAME ; \ echo 'rm "$(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/$$$$NEWNAME"' ; \ echo 'mv "$(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/$$$$FILENAME" "$(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/$$$$NEWNAME"' ; \ rm "$(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/$$$$NEWNAME" ; \ mv "$(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/$$$$FILENAME" "$(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/$$$$NEWNAME" ; \ done ls $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/ 

Я надеюсь, что эта информация поможет кому-то еще.

Похожие вопросы