I have made a command line application where I am zipping up folders and sharing on my local server for others to download. What I want to do is delete my copy of the zipped folder as soon as I close the server. This is my code:
func main() {
//flag to specify whether we will be uploading folder or a single file
zipped := flag.Bool("z",false,"Use for zipping folders and serving them as a single file on the server.(Deletes the zipped file once the server closes.)")
save := flag.Bool("s",false,"Use with -z for saving the zipped files locally even after the server closes.")
flag.Parse()
if len(flag.Args())>0{
if *zipped{
fmt.Println("zipping...")
flag.Args()[0]=ZipFile()
if !(*save){
//I expect this to remove the file when I hit ctrl+c on cmd
defer os.Remove(flag.Args()[0])
}
}
http.HandleFunc("/",ShareFile)
fmt.Printf("Sharing file on %s:8080\n",GetOutboundIP())
log.Fatal(http.ListenAndServe(":8080",nil))
}else{
fmt.Println("Invalid usage. No file mentioned. Use wshare -h for help.")
}
}
When I hit ctrl-c, the program exits and main function closes and as a result,shouldn't os.Remove(xyz) get executed? A tour of go says, defer executes the expression when the function returns. Here, I don't feel main gets the oppurtunity to return anything at all.
What is a workaround to achieve what I am trying to do? I have some solutions in my head like wait for a keypress etc. but I want this program to be super simple,so is there a way to delete the file as soon as the server closes/program exits without requiring any further input from me?
In the Go language, you are allowed to remove the existing file with the help of the Remove() method. This method removes the specified file from the director or it also removes empty directories.
In Go language, you are allowed to remove all the directories and files from a directory or folder with the help of RemoveAll() function. This function removes all the directories and files from the path you will pass to this function.
In the main() function, we created a file "Sample. txt" using os. Create() function and write text data into file using WriteString() file. The WriteString() function returns the number of characters written into the file.
To open a file in Golang, use the os. OpenFile() function. The reader and writer interfaces in Golang are similar abstractions. We read and write bytes without understanding where or how the reader gets its data or where the writer is sending the data.
This has already been answered in the comments, but I'll document it here for completeness.
defer
works only when the program and code you're using it in runs through its course normally. Stopping a program with with a command or killing it, on the other hand, sends a signal to the program and then terminates it abnormally, which does not allow the program to run all the defer
statements cleanly.
If you want to cleanup on OS termination, you can listen for OS signals - code based on the example here:
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
<- sigs
cleanupAllTheThings()
os.Exit(0)
}()
If you call this from main
, it will keep a goroutine running for the life of your program listening to the OS signals. And the cleanupAllTheThings()
function needs to be written to run as fast as possible without blocking to be effective - you never know when the OS is going to terminate you with prejudice.
Also, this will not protect you from someone pulling out the plug or a kernal panic - so it usually makes sense to have some kind cleanup of the old program state on startup or in a separate cleanup script.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With