После подстановки значения "$text_file" получается такая команда
perl -i -ne 'if (/BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/../END OF PRE-COMMIT-TERRAFORM DOCS HOOK/) { print $_ if /BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/; print "I_WANT_TO_BE_REPLACED\n$_" if /END OF PRE-COMMIT-TERRAFORM DOCS HOOK/;} else { print $_ }' README.md
Я попробовал запустить ее в терминале и увидел ошибку
$ perl -i -ne 'if (/BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/../END OF PRE-COMMIT-TERRAFORM DOCS HOOK/) { print $_ if /BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/; print "I_WANT_TO_BE_REPLACED\n$_" if /END OF PRE-COMMIT-TERRAFORM DOCS HOOK/;} else { print $_ }' README.md Can't remove README.md: Text file busy, skipping file.
Если убрать опцию
-i
, то команда отработает без ошибок и выдаст на STDOUT содержимое файла README.md с добавленной строкой "I_WANT_TO_BE_REPLACED" между маркерами. Выходит perl не может обновить файл при использовании опции -i
.Я уже сталкивался с особенностями работы virtualbox shared folders и первым делом попробовал эту команду вне точки монтирования vboxsf - отработала без ошибок. Ради интереса запустил под strace
$ strace perl -i -ne 'if (/BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/../END OF PRE-COMMIT-TERRAFORM DOCS HOOK/) { print $_ if /BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/; print "I_WANT_TO_BE_REPLACED\n$_" if /END OF PRE-COMMIT-TERRAFORM DOCS HOOK/;} else { print $_ }' README.md [skipped] open("README.md", O_RDONLY) = 3 ioctl(3, TCGETS, 0x7ffe4b254eb0) = -1 ENOTTY (Inappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = 0 fstat(3, {st_mode=S_IFREG|0744, st_size=897, ...}) = 0 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 unlink("README.md") = -1 ETXTBSY (Text file busy) write(2, "Can't remove README.md: Text fil"..., 55Can't remove README.md: Text file busy, skipping file. ) = 55 close(3) = 0 [skipped]
А вот и ограничение файловых систем Windows - нельзя удалить открытый файл. Если попробовать использовать переименование (
-i.bak
), то ошибка поменяется$ perl -i.bak -ne 'if (/BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/../END OF PRE-COMMIT-TERRAFORM DOCS HOOK/) { print $_ if /BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/; print "I_WANT_TO_BE_REPLACED\n$_" if /END OF PRE-COMMIT-TERRAFORM DOCS HOOK/;} else { print $_ }' README.md Can't rename README.md to README.md.bak: Text file busy, skipping file. $ strace perl -i.bak -ne 'if (/BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/../END OF PRE-COMMIT-TERRAFORM DOCS HOOK/) { print $_ if /BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/; print "I_WANT_TO_BE_REPLACED\n$_" if /END OF PRE-COMMIT-TERRAFORM DOCS HOOK/;} else { print $_ }' README.md [skipped] open("README.md", O_RDONLY) = 3 ioctl(3, TCGETS, 0x7fffc8ca5c50) = -1 ENOTTY (Inappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = 0 fstat(3, {st_mode=S_IFREG|0744, st_size=897, ...}) = 0 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 rename("README.md", "README.md.bak") = -1 ETXTBSY (Text file busy) write(2, "Can't rename README.md to README"..., 72Can't rename README.md to README.md.bak: Text file busy, skipping file. ) = 72 close(3) = 0 [skipped]
Переименовать открытый файл Windows тоже не дает - отсюда и постоянные требования перезагрузок при установке/обновлении/удалении софта. Примечательно что sed в такой конфигурации работает без ошибок
$ echo 123 > test $ strace sed -i -e 's/123/234/' test [skipped] open("test", O_RDONLY) = 3 ioctl(3, TCGETS, 0x7fff82ffc3a0) = -1 ENOTTY (Inappropriate ioctl for device) fstat(3, {st_mode=S_IFREG|0744, st_size=4, ...}) = 0 umask(0700) = 022 getpid() = 13309 open("./sedAkH6bM", O_RDWR|O_CREAT|O_EXCL, 0600) = 4 umask(022) = 0700 fcntl(4, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE) fstat(3, {st_mode=S_IFREG|0744, st_size=4, ...}) = 0 read(3, "123\n", 4096) = 4 fstat(4, {st_mode=S_IFREG|0744, st_size=0, ...}) = 0 write(4, "234\n", 4) = 4 read(3, "", 4096) = 0 fchown(4, 1000, 1000) = 0 fchmod(4, 0100744) = 0 close(3) = 0 close(4) = 0 rename("./sedAkH6bM", "test") = 0 [skipped]
Вместо удаления открытого файла sed делает копию открытого исходного файла, обрабатывает ее, закрывает оба файла и заменяет оригинал копией. Нужно будет попробовать пожить с WSL и посмотреть какие грабли выплывут.
Комментариев нет:
Отправить комментарий