(Veja a atualização no pé da pergunta).
Esta é uma pergunta de acompanhamento para "Fazer cópias de diretório usando
encontrar ".
Esta questão envolveu manipular um monte de diretórios.
muito complicado para lidar com um único comando, então eu decidi ir com
uma abordagem que salvou a lista de diretórios para um array bash,
apesar das reservas sobre portabilidade. Parece que o shell POSIX
padrão (o padrão shell Unix, como eu o entendo) não tem
matrizes.
O makefile que estou usando aparece abaixo. Isso funciona, exceto pelo último
degrau. Um resumo do que estou tentando fazer é seguir.
Como discutido na pergunta anterior, quero dar uma olhada no
diretório x86-headers
, e coletar em uma matriz bash, uma lista de seus
subdiretórios de nível superior que contêm o arquivo C/populate.sh
(mas
também contém outros arquivos). Na minha configuração de teste, por exemplo, há apenas
um diretório em x86-headers
que contém o arquivo libc/C/populate.sh
, a saber
libc
.
Eu então executo algumas operações nesses subdiretórios. A maioria
importante é que eu faça uma cópia temporária de cada diretório
que parece com libc.tmp_g4zlb
. Ou seja, dirname seguido por 'tmp_'
seguido por uma string aleatória de 5 dígitos.
Então, algumas perguntas:
1) Como discutido na pergunta anterior, estou dando voltas
diretório 'x86-headers'. Aqui eu ainda estou usando o find. @Gilles indicou
em sua resposta que esta
não era ideal. Ele pode estar certo. Problemas com encontrar aqui:
a) Os valores retornados parecem com ./libc
. Eu não quero um líder
./
.
b) O comando de localização que estou usando lista todos os diretórios. Eu só quero
considere aqueles que contêm um arquivo com o caminho relativo de
C/populate.sh
.
A abordagem que Gilles estava usando poderia ser melhor, mas eu não entendo
isto. Veja a meta gilles
abaixo. Eu gostaria de obter a lista dos
diretórios e salvá-los em um array.
2) A parte que estou tendo problemas é o último passo, a saber
echo "(progn (require 'parse-ffi) (ccl::parse-standard-ffi-files :$$i'.tmp_'$(RND)))" | \
/usr/lib/ccl-bootstrap/lx86cl -I /usr/lib/ccl-bootstrap/lx86cl.image; done \
O bit relevante é que estou tentando passar o valor temporário
libc.tmp_g4zlb
para ccl, que é um compilador Common Lisp. Sem o
substituição, seria parecido com
echo "(progn (require 'parse-ffi) (ccl::parse-standard-ffi-files :libc.tmp_g4zlb))" | \
/usr/lib/ccl-bootstrap/lx86cl -I /usr/lib/ccl-bootstrap/lx86cl.image; done \
Isso funciona. A versão usando $$i
acima não. O problema parece
para ser o líder ./
. Sem isso, deveria funcionar. Para o registro, o erro que recebo é
? > Error: Too many arguments in call to #<Compiled-function CCL::PARSE-STANDARD-FFI-FILES #x488B8406>:
> 3 arguments provided, at most 2 accepted.
> While executing: CCL::PARSE-STANDARD-FFI-FILES, in process listener(1).
Este não é, no entanto, o erro que recebo ao passar ./libc.tmp_g4zlb
para o compilador. Esse erro parece
> Error: Filename "/home/faheem/test/foo/x86-headers/.\/libc.tmp_g4zlb/C/**/" contains illegal character #\/
> While executing: CCL::%SPLIT-DIR, in process listener(1).
Então é possível que haja algo mais acontecendo.
3) A abordagem geral parece razoável? Por favor fique a vontade para
sugerir possíveis melhorias, mesmo que envolva uma completa
estratégia diferente.
#!/usr/bin/make -f
# -*- makefile -*-
export SHELL=/bin/bash
export RND:=$(shell tr -cd a-z0-9 < /dev/urandom | head -c5)
export CCL_DEFAULT_DIRECTORY=$(CURDIR)
clean:
rm -rf x86-headers/libc.tmp*
foo: clean
PATH=$$PATH:$(CURDIR)/ffigen4/bin; \
echo $$PATH; \
export CURDIR=$(CURDIR); \
echo $$CURDIR; \
array=( $$(cd x86-headers && find . -mindepth 1 -maxdepth 1 -type d) ); \
cd x86-headers && \
for i in "$${array[@]}"; do \
echo $$i; done; \
for i in "$${array[@]}"; do \
mkdir -p $$i."tmp_"$(RND)/C; done; \
for i in "$${array[@]}"; do \
cp -p $$i/C/populate.sh $$i".tmp_"$(RND)/C; done; \
for i in "$${array[@]}"; do \
cd $$i".tmp_"$(RND)/C; ./populate.sh; done; \
for i in "$${array[@]}"; do \
echo $$i'.tmp_'$(RND); done; \
for i in "$${array[@]}"; do \
echo "(progn (require 'parse-ffi) (ccl::parse-standard-ffi-files :$$i'.tmp_'$(RND)))" | \
/usr/lib/ccl-bootstrap/lx86cl -I /usr/lib/ccl-bootstrap/lx86cl.image; done; \
gilles:
cd x86-headers;
for x in */C/populate.sh; do \
echo -- "$${x%%/*}$$suffix"; done; \
ATUALIZAÇÃO: É possível que a pergunta (ou perguntas) tenha se perdido em todos os detalhes. Então, deixe-me tentar simplificar as coisas. Em sua resposta , escreveu Gilles
for x in */C/populate.sh; do
mkdir -- "${x%%/*}$suffix"
mkdir -- "${x%%/*}$suffix/C"
cp -p -- "$x" "./${x%%/*}$suffix/C"
done
Como comentei a pergunta dele, x
aqui corresponde a padrões do formulário */C/populate.sh
. Além disso, ${x%%/*}
corresponde à primeira parte da sequência, ou seja, o nome do diretório de nível superior. Agora, algo como
for x in */C/populate.sh; do
myarr[] = "${x%%/*}"
done
criaria uma matriz contendo uma lista de diretórios de nível superior, que é o que eu quero. No entanto, não sei qual sintaxe usar. Eu preciso usar um contador que executa o loop, como i=0, 1,...
para indexar myarr
no LHS. Se eu tivesse um código de trabalho como esse, resolveria meu problema.