chef notification after a change in a directory - directory

What is the best way to make chef trigger a notification after a file changes within a directory structure?
I would like chef to scan the directory recursively for changes. I am not too sure what is the best approach, maintain a checksum or check timestamps within the directory.
My usecase seems quite common, but I could not find an exact match when googling.
My current attempt looks like:
directory "/tmp/myfiles" do
notifies :run, "script[myscript]", :delayed
end
script "myscript" do
interpreter 'bash'
code <<-SH
echo "hello world"
SH
action :nothing # only run when notified
end
And does not print "hello world" as expected if the directory exists.

Related

If i let a tail -f running on a file, does it prevent it from being deleted?

The operating system is AIX. I have done multiple tests by running tail -f commands on text files. Then from another terminal session i try to delete the tailed file. I have always been successful to delete them and no problem occurred but i did not find any factual documentation saying that tail -f does not lock or prevent a file from being deleted. So i would like to know if there is such a formal information and if the tail command may lock or prevent a file from being deleted how can i reproduce the use case ?
I suspect that the unlink() system call in AIX behaves similar enough to Linux that the first paragraph in this Linux man page adequately describes it:
unlink deletes a name from the filesystem. If that name was the last
link to a file and no processes have the file open the file is deleted
and the space it was using is made available for reuse.
When removing large log files that are being tailed (or written to), the disk space isn't free'd until all these processes close the file or terminate.
You can delete/move file while tail -f , but it will not create if deleted, have to create manually, hope this helps.

R - write() a file to a SAMBA share

I have a file loaded in R that I want to move to a samba share
It is something like
write(some-file, file = "|smbclient -U user //ip password")
It connects to the samba but then (I think) the output is "executed" in the smb: \> and I don't want the file to be executed, I don't know how to pass the file to the destination with a putfunction inside smbclient.
Edit: This is not the same problem as the first post. The first post is solved and answered by me. The point there was connecting to samba. Now I'm already connected to it but the write() function doesn't make a file, instead it pipes out the words separately. I just wanted to know how to make it create a file in a sentence.
I found the answer by changing the philosophy:
First, I write the file locally, like
write(some-file, there)
Then I use the system() function to call smbclient and put the file already written
system("smbclient -U user //ip/dir password -c \"put some-file some-file\"")
My script is more complex and it's inside a Shiny app but in summary that's the solution

Update current working directory after vim netrw exit

Here's the scenario.
I am on the unix command line (in home directory). I want to browse the directory through
$ vim .
thus opening the vim netrw.
Now I am browsing the directory using the netrw.
What I want here is that when I exit vim netwr, I want my previous current working directory (in this example the home directory) to now become the directory I was previously in vim netrw.
Example:
step 1. now in home directory
step 2. vim . (thus opening vim netrw)
step 3. go to any directory (~/my/other/folders)
step 4. :q (to exit vim)
step 5. (here, I want my previous directory to now become ~/my/other/folders
any ideas on how to do it? I was thinking of doing something in .vimrc but I dunno how. Been into google search, but found nothing valuable.
A possible solution would be to change the current work directory while in netrw by pressing c, and spawn a new shell from the folder you're in by issuing :shell
So it would look like:
vim .
Navigate to the desired folder...
c
:shell
And there you are in a shell in the current folder you were in netrw.
And when you exit that shell, you fall back to where you were in netrw and can continue using the explorer.
I don't think it's possible at all. Every command executed via system('command') or :!command is executed through a subshell, not through the shell that started Vim so I don't see how you could alter the host shell in any way.
But I smell an XY problem here. What is your goal?
Do you want to be able to execute some commands on the files you just edited and you want to be in their directory? If so, do you know about :sh? :!command?
Do you want a "graphical" file explorer for your shell? If so, do you know vifm? Ranger? Midnight Commander?
To add to Wadih's answer, you can put this in your .vimrc file:
let g:netrw_keepdir=0
This means the working directory will be automatically updated and you don't need to press c each time.
So after navigating to a folder in netrw, all you need to do is do this:
:sh
And this opens the terminal in the current folder.
From the netrw help file:
By default, g:netrw_keepdir is 1. This setting means that the current
directory will not track the browsing directory. (done for backwards
compatibility with v6's file explorer).
Setting g:netrw_keepdir to 0 tells netrw to make vim's current directory
track netrw's browsing directory.

Using execlp after jailing a process

Basically I want to execute a shell command inside a jailed process. When I try the below code(both as a normal user & root user), it produced no output
if(!(pid=fork)){
chroot("./jail_folder");
chdir("/");
execl("/bin/ls","ls",NULL);
}
I tried the perror() function and it gave me a "No such file or directory" error.
Is it possible to run a shell command in a jailed process? If so, how do we do that?
Yes, it is possible, but you have to make it accessible to the jail (typically, it means copying the desired program + all its libraries to the jail; symlinking wouldn't work, hardlinking is OK). Otherwise, it's no surprise that if you confine a program to part of the directory tree without /bin, you can't access /bin/ls.

What is the Unix way for a console script to use config files?

Let's imagine we have some script 'm12' (I've just invented this name) that runs
on Linux computers. If it is situated in your $PATH, you can easily run it
from the console like this:
m12
It will work with the default parameters. But you can customize the work of
this script by running it something like:
m12 --enable_feature --select=3
It is great and it will work. But I want to create a config file ~/.m12rc so I
will not need to specify --enable_feature --select=3 every time I run it.
It can be easily done.
The difficult part is starting here.
So, I have ~/.m12rc config file, but I what to start m12 without parameters that
are stored in that config file. What is the Unix way to do this? Should I run
script like this:
m12 --ignore_config
or there is better solution?
Next. Let's imagine I have a config file ~/.m12rc and I want some parameters from that
file, but want to change them a bit. How should I run the script and how the
script should work?
And the last question. Is it a good idea for script to first look for .m12rc
in the current directory, then in ~/ and then in /etc?
I'm asking all these questions because I what to implement config files in my
small script and I want to make the correct decisions about the design.
The book 'The Art of Unix Programming' by E S Raymond discusses such issues.
You can override the config file with --config-file=/dev/null.
You would normally use the order:
System-wide configuration (/etc/m12/m12rc, or just /etc/m12).
User's personal configuration (~/.m12rc)
Local directory configuration (./.m12rc)
Command-line options
with each later-listed item overriding earlier listed items. You should be able to specify the configuration file to read on the command line; arguably, that should be given precedence over other options. Think about --no-system-config or --no-user-config or --no-local-config. Many scripts do not warrant a system config file. Most scripts I've developed would not use both local config and user config. But that's the way my mind works.
The way I package standard options is to have a script in $HOME/bin (say m12a) that does it for me:
#!/bin/sh
exec m12 --enable_feature --select=3 "$#"
If I want those options, I run m12a. If I want some other options, I run raw m12 with the requisite options. I have multiple hundreds of files in my personal bin directory (about 500 on my main machine, a Mac; some of those are executables, but many are scripts).
Let me share my experience. I normally source config file at the beginning of the script. In the config file I also handle all the parameter switches:
DEFAULT_USER=blabla
while getopts ":u" do
case $opt in
u)
export APP_USER=$OPTARG
;;
esac
done
export APP_USER=${APP_USER-$DEFAULT_USER}
Then within the script I just use variables, this let me to have number of script having same input parameters.
In your case I imaging you would move "getopts" section to script and after it source the config file (if there was no switch to skip sourcing).
You should not put yours script config file to etc, it will require root privilidge to do that, and you simple can live with config file in home.
If you would like anyway to put your script for sharing with other users, it should go to /usr/share...
Another solution use thor (ruby gem), its way simpler to handle input parameter, avoiding work to get same result in bash e.g. getopts support only single letter switches.

Resources