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

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

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

у меня есть renamefiles.sh которая отлично работает

#!/bin/sh
for i in $i
 do
   echo $i
   echo mv "${i}" "${f//-/:}";
   mv "${i}" "${f//-/:}";
 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 будет делать работу хорошо, но я был предупрежден, потому что это не доступно везде.

1 ответ

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

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

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

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

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

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

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

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

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

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

Теперь о том, чтобы поместить его в 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=$$$${FILENAME//-/:} ; \
    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/

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

Другие вопросы по тегам