#python #makefile
#python #makefile
Вопрос:
У меня есть каталог ~/PROJECTS
, содержащий несколько подкаталогов, некоторые из которых являются символическими ссылками на другие каталоги.
.
├── proj1_symlink_dir
├── proj2_symlink_dir
├── proj3_symlink_dir
├── backup_1_dir
├── backup_2_dir
Каждый из этих каталогов символических ссылок (которые указывают на другие каталоги
на моем жестком диске), т.е.
[proj1_symlink_dir, proj2_symlink_dir, proj3_symlink_dir]
каждый содержит Makefile
.
Я хочу написать python
скрипт для:
- Перебирайте только символические ссылки в active directory
- Для каждой из этих символических ссылок перейдите в каталог и запустите
make clean
(или с учетом строкового параметра, содержащего команды make)
Может ли кто-нибудь помочь в написании компактного скрипта на pythonic для выполнения вышеуказанной задачи?
Пока у меня есть следующее для печати символических ссылок (адаптировано отсюда):
dirname = os.getcwd()
for name in os.listdir(dirname):
if name not in (os.curdir, os.pardir):
full = os.path.join(dirname, name)
if os.path.islink(full):
print(name, '->', os.readlink(full))
Я не уверен, как безопасно работать с запущенными Makefile
командами в python
Обновить
С помощью @Marat я создал следующий скрипт с именем runmke.py
.
#!/Usr/bin/env python
import argparse
import os
import json
def run_symlink_makefile_cmd(dirname, make_cmds, verbose):
"""
Run common make commands from makefiles from
all symlinked directories that are located
in a specified directory
"""
make_cmds_str = " ".join(make_cmds)
for name in os.listdir(dirname):
if name not in (os.curdir, os.pardir):
full = os.path.join(dirname, name)
if os.path.islink(full):
if verbose:
print(f"n>>>>> Running the Make command:")
print(f"make -C {full} {make_cmds_str}")
os.system(f"make -C {full} {make_cmds_str}")
def main(dirname, make_cmds, verbose):
# Display parameters passed for the given run (includes defaults)
print(f"""The parameters for this run are:n {json.dumps(locals(), indent=2, default=str)}""")
run_symlink_makefile_cmd(dirname=dirname,
make_cmds=make_cmds,
verbose=verbose)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--dirname', action='store', default=os.getcwd(),
help='The directory in which symlink directories, default is the current directory')
parser.add_argument('-m', '--make_cmds', nargs=' ',
default=["clean", "latex_style"],
help='These are the Makefile commands to run')
parser.add_argument('-v', '--verbose', action='store_true', default=True,
help='If true, print updates while processing.')
argument_parsed = parser.parse_args()
main(
dirname=argument_parsed.dirname,
make_cmds=argument_parsed.make_cmds,
verbose=argument_parsed.verbose
)
Однако, когда я запускаю ./runmke.py -m latex_style -v False
свой терминал, я получаю сообщение об ошибке:
usage: runmke.py [-h] [-d DIRNAME] [-m MAKE_CMDS [MAKE_CMDS ...]] [-v]
runmke.py: error: unrecognized arguments: False
Любые идеи, почему verbose
логический аргумент не распознается.
Это работает, когда я не передаю это вручную.
Комментарии:
1. что вы пробовали до сих пор?
2. @Marat — я добавил еще несколько подробностей о том, где я нахожусь
3. кажется, вам не хватает только одной строки под инструкцией print:
os.system('make -C "%s" clean' % full)
4. @Marat — большое спасибо за вашу любезную помощь. Я добавил свой обновленный код с вашей помощью в качестве скрипта в свой исходный пост. Это имеет небольшую ошибку. Не могли бы вы помочь? Если вы напишите ответ в виде полного ответа, я могу принять его, чтобы вы получили должное признание за решение
5.
action=store_true
аргументы типа не имеют значения, им присваивается значение True, если ключ просто присутствует в команде. Итак, правильная команда для запуска:./runmke.py -m latex_style -v
Ответ №1:
С помощью @Marat я создал следующий скрипт с именем runmke.py
.
#!/Usr/bin/env python
import argparse
import os
import json
def run_symlink_makefile_cmd(dirname, make_cmds, verbose):
"""
Run common make commands from makefiles from
all symlinked directories that are located
in a specified directory
"""
make_cmds_str = " ".join(make_cmds)
for name in os.listdir(dirname):
if name not in (os.curdir, os.pardir):
full = os.path.join(dirname, name)
if os.path.islink(full):
if verbose:
print(f"n>>>>> Running the Make command:")
print(f"make -C {full} {make_cmds_str}")
os.system(f"make -C {full} {make_cmds_str}")
def main(dirname, make_cmds, verbose):
# Display parameters passed for the given run (includes defaults)
print(f"""The parameters for this run are:n {json.dumps(locals(), indent=2, default=str)}""")
run_symlink_makefile_cmd(dirname=dirname,
make_cmds=make_cmds,
verbose=verbose)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--dirname', action='store', default=os.getcwd(),
help='The directory in which symlink directories, default is the current directory')
parser.add_argument('-m', '--make_cmds', nargs=' ',
default=["clean", "latex_style"],
help='These are the Makefile commands to run')
parser.add_argument('-v', '--verbose', action='store_true', default=True,
help='If true, print updates while processing.')
argument_parsed = parser.parse_args()
main(
dirname=argument_parsed.dirname,
make_cmds=argument_parsed.make_cmds,
verbose=argument_parsed.verbose
)
Его можно запустить на терминале с помощью ./runmke.py -m latex_style -v