fabric.contrib.files.append does not handle input with newlines correctly
See original GitHub issueIn Fabric 1.13.2, the following code produces unexpected results
from fabric.contrib.files import append
append('file.txt', 'a') # appended
append('file.txt', 'b') # appended
append('file.txt', 'c\n') # not appended
append('file.txt', 'a\nd') # not appended
The resulting file.txt
has the following content
a
b
This behaviour is not present in Fabric 1.13.1. It looks like _escape_for_regex
is not properly escaping newlines.
Issue Analytics
- State:
- Created 6 years ago
- Comments:8
Top Results From Across the Web
File and Directory Management - Fabric documentation
When a list is given, each string inside is handled independently (but in the order given.) If text is already found in filename...
Read more >How to append new data onto a new line - python
It just concatenates your string, name , and that newline character into a bigger string, which gets written to the file.
Read more >Fabric - Read the Docs
Fabric is a high level Python (2.7, 3.4+) library designed to execute shell commands remotely over SSH, yielding useful.
Read more >Chapter 9. Automating Deployment with Fabric - O'Reilly
from fabric.contrib.files import append , exists , sed from fabric.api ... but not clever enough to automatically add a newline if the file...
Read more >Bug listing with status RESOLVED with resolution OBSOLETE ...
systemPrefs with at least two files" status:RESOLVED resolution:OBSOLETE ... Bug:377749 - "libbash doesn't handle \newline properly" status:RESOLVED ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
The problem is with how egrep handles newline characters.
contrib.append()
is described as:grep/egrep is also explicitly about matching lines. I don’t think there’s any way to do multiple-line patterns with egrep. So, it seems that newline characters in the egrep pattern are considered to separate multiple patterns, any of which can match. So “\n$” matches every line, and “anything\n$” also matches every line. So
append()
always thinks the line is already present.How did it work before? Newlines were effectively removed from the line when it was being checked (as a pattern). Thus typically no match, so it was appended. For example,
was run by Fabric 1.13.1 as:
In the shell, backslash-newline means to ignore the newline. So this was equivalent to:
So if you ran
append()
twice, it would append twice, which the documentation said it should not do, it should only append once. The second time it would not find what it had just appended.Conclusions:
contrib.files.append()
does not handle newline characters correctly. It never has, but it changed from “usually erroneously append” to “usually erroneously don’t append”. The documentation does say it’s for lines, after all … but it does “break” some backwards compatibility … but then again, it’s “contrib” …For unconditionally appending multi-line strings, you should probably just
EDIT: expanded quote of
append()
documentation to include mention of linesFabric 2.x doesn’t have this helper function (or any of contrib).
However, this is fixed in my fork of Fabric 1.x https://github.com/ploxiln/fab-classic
EDIT: well, somewhat fixed, the model of being based on egrep has limitations