8000 WriteFile occassionaly truncates files entirely · Issue #137 · bitfield/script · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

WriteFile occassionaly truncates files entirely #137

New issue

Have a question about this project? Sign up for a free GitHub account to open an iss 8000 ue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
klauern opened this issue Oct 27, 2022 · 6 comments
Open

WriteFile occassionaly truncates files entirely #137

klauern opened this issue Oct 27, 2022 · 6 comments

Comments

@klauern
Copy link
klauern commented Oct 27, 2022

I am trying to write a simple sed -i script using this, but it seems that when I run it on the same path that I am reading it from, occasionally the file is completely truncated instead of written with the piped changes.

func Replace(path, from, to string) error {
	pipe := script.File(path)
	file, err := pipe.Replace(from, to).WriteFile(path)
	if err != nil {
		fmt.Println(path, err)
		return fmt.Errorf("error writing file %s: %w", path, err)
	}
    return nil
}

I can make this work by pulling the write operation out of the pipe:

func Replace(path, from, to string) error {
	pipe := script.File(path)
	file, err := pipe.Replace(from, to).String()
	if err != nil {
		fmt.Println(path, err)
		return fmt.Errorf("error writing file %s: %w", path, err)
	}
	return os.WriteFile(path, []byte(file), 0644)
}
@klauern
Copy link
Author
klauern commented Oct 27, 2022

What's frustrating is that this isn't the case all the time, so it does work for a good percentage, so there is some kind of weird race condition that is causing it not to work. I am not running any of these calls in parallel, so I am pretty sure it's how the file is handled in bitfield/script itself.

@bitfield
Copy link
Owner

I'm not sure it's safe to write to a file at the same time as reading from it—or rather, it's safe, but might give you puzzling results, as you've experienced. The reads and writes will be buffered, which means the bits don't necessarily show up on disk when you expect them to.

@klauern
Copy link
Author
klauern commented Oct 27, 2022

I was thinking that, too. I thought maybe the Wait() command would let me do that, but since it doesn't return a *Pipe, that seemed like a dead-end.

@andrew-werdna
Copy link

I've encountered the same issue as well. Filters run concurrently as stated in the readme, and it doesn't look like there is an option to enforce consecutive execution. I was trying to do the exact same thing as you @klauern and I solved it the same way too.

@bitfield
Copy link
Owner
bitfield commented Nov 7, 2022

Another option that avoids reading the whole file into memory would be to pipe it to a temporary file, and then once the pipe has completed, rename the temporary file to the original file.

@zhqqqy
Copy link
zhqqqy commented Mar 21, 2025

Another option that avoids reading the whole file into memory would be to pipe it to a temporary file, and then once the pipe has completed, rename the temporary file to the original file.

yes, i used ioutil.TempFile("", "temp.txt") to create a temporary file. Perhaps this could be encapsulated into an internal method to be used with Replace function ? Like sed -i.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
0