Can't embed bash command in to Chef Recipe - bash

I'm attempting to embed a shell command in to my Chef Recipe, however when Chef executes the command it seems to get things wrong. Here's the resource in question:
script "create libs symlink" do
interpreter "bash"
user "root"
cwd "/home/robin/test"
code <<-EOH
ln -s $(ls -1 | grep '^[0-9.-]\+$') curr-version-libs
EOH
end
The /home/robin/test directory contains a folder called 19.26-3, so I'm expecting a symlink called curr-version-libs pointing at 19.26-3.
Instead, I'm ending up with a circular symlink:
drwxr-xr-x 4 root root 4096 Jan 17 22:35 19.26-3
drwxr-xr-x 2 root root 4096 Jan 17 22:35 config
lrwxrwxrwx 1 root root 17 Jan 28 17:31 curr-version-libs -> curr-version-libs
It seems that the $(ls -1 | grep '^[0-9.-]+$') is being removed and I'm ending up with the command ln -s curr-version-libs.
Does anyone know what's going on here? I've tried using an execute resource, but I get the same results.

If your 19.26-3 directory exists before chef run starts, then it is easy. If you are creating a symbolic link, I would recommend using link resource for that.
version = `ls /home/robin/test/ -1 | grep '^[0-9.-]+$'`.strip
link "/home/robin/test/curr-version-libs" do
to ::File.join( "/home/robin/test", version )
end
But if it is not there, I would recommend using ruby_block and defining your link resource dynamically.
ruby_block "create libs symlink" do
block do
version = `ls /home/robin/test/ -1 | grep '^[0-9.-]+$'`.strip
res = Chef::Resource::Link.new( "/home/robin/test/curr-version-libs", run_context )
res.to ::File.join( "/home/robin/test", version )
res.run_action :create
end
end
Edit: I corrected the answer by fixing regex and and calling strip before assigning to version as Robin proposed.

It appears you are calling out to the shell to create a sym link. In that case, a much better way to do this is to use the Chef link resource. I would never use the script or execute resource to do what you are doing.
Using the link resource, you would do the following:
link "/home/robin/test/curr-version-libs" do
to '/home/robin/test/19.26-3'
user 'root'
group 'root'
link_type :symbolic
action :create
end
A quick side commentary: I have mentored and tutored a number of folks to come up on Chef. Those who come to understand what is offered by the resources, providers, and lightweight resources (aka. LWRPs) are much happier and effective than those who just try to drop their old shell scripts into their cookbooks.
I highly recommend reading the Resource and Providers and Lightweight Resources Documentation

have you tried escaping dollar sign?
ln -s \$(ls -1 | grep '^[0-9.-]\+$') curr-version-libs

Related

How to insert the configuration.nix file inside my dot files?

I am creating my dot files following this tutorial. It successfully works for emacs.d.
Since I am using NixOS, I tried doing exactly the same steps with symlink creation for the configuration.nix file. Thus, I did:
1 - On terminal:
[pedro#system:/etc/nixos]$ sudo mv /etc/nixos/configuration.nix ~/.dotfiles/
2 - Then:
[pedro#system:/etc/nixos]$ ln -sf ~/.dotfiles/configuration.nix configuration.nix~
3 - It seems to work fine, as I do:
[pedro#system:/etc/nixos]$ ls -la
total 12
drwxr-xr-x 2 root root 4096 Dec 1 21:41 .
drwxr-xr-x 32 root root 4096 Dec 1 22:00 ..
lrwxrwxrwx 1 root root 39 Dec 1 21:41 configuration.nix~ -> /home/pedro/.dotfiles/configuration.nix
-rw-r--r-- 1 root root 842 Nov 12 17:40 hardware-configuration.nix
After doing some editions and saving the changes, I can't do nixos-rebuild switch, though. It throws an error:
[pedro#system:/etc/nixos]$ sudo nixos-rebuild switch
warning: Nix search path entry '/etc/nixos/configuration.nix' does not exist, ignoring
error: file 'nixos-config' was not found in the Nix search path (add it using $NIX_PATH or -I), at /nix/var/nix/profiles/per-user/root/channels/nixos/nixos/default.nix:1:60
(use '--show-trace' to show detailed location information)
building Nix...
warning: Nix search path entry '/etc/nixos/configuration.nix' does not exist, ignoring
error: file 'nixos-config' was not found in the Nix search path (add it using $NIX_PATH or -I), at /nix/var/nix/profiles/per-user/root/channels/nixos/nixos/default.nix:1:60
(use '--show-trace' to show detailed location information)
building the system configuration...
warning: Nix search path entry '/etc/nixos/configuration.nix' does not exist, ignoring
error: file 'nixos-config' was not found in the Nix search path (add it using $NIX_PATH or -I), at /nix/var/nix/profiles/per-user/root/channels/nixos/nixos/default.nix:1:60
(use '--show-trace' to show detailed location information)
The ~ after configuration.nix~ might be the problem here. How can I fix this?
Thanks!
Your Step 2 seems to have cause the issue here: The symlink should be called configuration.nix not configuration.nix~ as you have noticed.
You could fix this by running mv configuration.nix~ configuration.nix in the /etc/nixos folder which would rename configuration.nix~ to the correct configuration.nix.

Recursively searching a directory without changing directory atimes

I'm checking an alternative to 'find' command in shell scripting so as to eliminate the discrepancy of Accessed date of sub directories.
According to my observation, when find command is executed to list all the files in a directory, the accessed date of sub-directories is getting changed.
I want to post genuine statistics in one of the junk platforms, So I have been looking at some forums and got the alternative with 'ls' command. But that doesn't completely fulfill my request.
Below is the answer given by #ghostdog74.
ls -R %path% | awk '/:$/&&f{s=$0;f=0} /:$/&&!f{sub(/:$/,"");s=$0;f=1;next} NF&&f{ print s"/"$0 }'.
But this finds only the files inside the sub directories. I need all the files and sub-directories' files to be listed.
For example:
bash-3.2# pwd
/Users/manojkapalavai/Desktop/SleepTimeReport
bash-3.2# ls
**6th floor** manoj17 manoj26.txt manoj36 manoj45.txt manoj55 manoj70.txt manoj80 manoj9.txt **test1**
manoj14 manoj23.txt manoj33 manoj42.txt manoj52 manoj61.txt manoj71 manoj80.txt manoj90 **test2**.
The highlighted ones are sub-directories inside "SleepTimeReport" directory and remaining are just files. So, when I execute the above command, I get only the below output.
bash-3.2# ls -R ~/Desktop/SleepTimeReport | awk '/:$/&&f{s=$0;f=0} /:$/&&!f{sub(/:$/,"");s=$0;f=1;next} NF&&f{ print s"/"$0 }'.
~/Desktop/SleepTimeReport/6th floor/Script to increase the Sleep Time.numbers.
~/Desktop/SleepTimeReport/6th floor/Zone1Sleep.pages.
~/Desktop/SleepTimeReport/test1/New_folder.
~/Desktop/SleepTimeReport/test1/manoj.txt.
~/Desktop/SleepTimeReport/test1/sathish.txt.
~/Desktop/SleepTimeReport/test1/vara.txt.
~/Desktop/SleepTimeReport/test1/New_folder/Script to increase the Sleep Time.numbers.
~/Desktop/SleepTimeReport/test1/New_folder/Zone1Sleep.pages.
i.e.; only those files inside sub-directories are listed.
Brief explanation of what issue I'm facing, please see below
Manojs-MacBook-Pro:SleepTimeReport manojkapalavai$ ls -l
total 16
drwxr-xr-x 8 manojkapalavai staff 272 Sep 14 15:07 6th floor
-rwxr-xr-x 1 manojkapalavai staff 59 Nov 13 10:41 AltrFind.sh
-rw-r--r-- 1 manojkapalavai staff 0 Nov 2 15:15 manoj%.txt
-rw-r--r-- 1 manojkapalavai staff 0 Nov 2 18:23 manoj1
When I try finding Created time and Accessed Time of the folder 6th floor before using 'find' command, the below is output.
Manojs-MacBook-Pro:SleepTimeReport manojkapalavai$ stat -f '%N, %SB, %Sa' 6th\ floor/
6th floor/, Sep 13 10:34:55 2017, **Nov 13 11:21:33 2017**
Manojs-MacBook-Pro:SleepTimeReport manojkapalavai$ find /Users/manojkapalavai/Desktop/SleepTimeReport/
/Users/manojkapalavai/Desktop/SleepTimeReport/
/Users/manojkapalavai/Desktop/SleepTimeReport//6th floor
/Users/manojkapalavai/Desktop/SleepTimeReport//6th floor/.DS_Store
/Users/manojkapalavai/Desktop/SleepTimeReport//6th floor/Script to increase the Sleep Time.numbers
/Users/manojkapalavai/Desktop/SleepTimeReport//6th floor/Zone1Sleep.pages
Now, after finding all the files inside a directory, below is the output of atime. you can notice the change
Manojs-MacBook-Pro:SleepTimeReport manojkapalavai$ stat -f '%N, %SB, %Sa' 6th\ floor/
6th floor/, Sep 13 10:34:55 2017, **Nov 13 14:26:03 2017**
All tha I have done is just find the files, and atime of sub-folders inside a folder when we find is getting changed to that current time.
Is there any way to solve this?
ls is the wrong tool for programmatic use. Generally, you should be able to fix your find usage to not have an effect on atimes (actually, it's pretty rare for folks to even have atimes enabled at the filesystem level on modern production systems), but if you really want to avoid it, consider the bash globstar option:
shopt -s globstar
for file in **/*; do
echo "Doing whatever with $file"
done

Windows API to access case-sensitive paths (Bash-on-Ubuntu-on-Windows)

Bash-on-Ubuntu-on-Windows supports case-sensitive file paths. This means that I can create two files or directories with names only differing in capitalization. I have issues accessing those files, though.
Running
bash -c "touch Magic ; mkdir magic ; echo Secret! > magic/secret"
Creates a file names Magic, a directory named magic and a file names secret in that directory.
bash -c "ls -lR" yields
.:
total 0
drwxrwxrwx 2 root root 0 Aug 23 10:37 magic
-rwxrwxrwx 1 root root 0 Aug 23 10:37 Magic
./magic:
total 0
-rwxrwxrwx 1 root root 8 Aug 23 10:37 secret
(I am not sure why I get root, as it is not the default user, but that does not seem relevant to my question.)
Windows Explorer shows:
Now, while bash can easily access the magic/secret file in the directory, Windows seems to treat both the directory and the file as one and the same. So double-clicking the directory I get a "directory name invalid" error
Same goes for using cd, as I get The directory name is invalid. printed out.
Are there any APIs that allow me to access those case-sensitive paths, or create them? It seems that regular Windows APIs ignore character case completely when accessing existing files.
Case-sensitive paths can be used on Windows with NTFS, but it requires a bit of extra work.
First, case-sensitivity must be enabled system-wide. This is done by setting the HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\kernel\ dword:ObCaseInsensitive registry value to 0, then restarting the system.
I found this part here.
Once case-sensitivity is enabled, it is possible to use CreateFile to with case-sensitive paths. To do that, you have to pass the FILE_FLAG_POSIX_SEMANTICS as part of the dwFlagsAndAttributes parameter. From msdn:
Access will occur according to POSIX rules. This includes allowing multiple files with names, differing only in case, for file systems that support that naming.
I found this part in this answer.
By setting the registry setting and the CreateFile flag, I was able to access case-sensitive paths.

Checking output from "command" should contain unexpected crash with NilClass

In an effort to use Cucumber for a command-line script, I've installed the aruba gem as per the instructions provided. It's in my Gemfile, I can verify that the correct version is installed and I've included
require 'aruba/cucumber'
in 'features/env.rb'
In order to ensure it works, I wrote the following scenario:
#announce
Scenario: Testing cucumber/aruba
Given a blank slate
Then the output from "ls -la" should contain "drw"
assuming the thing should fail.
It does fail, but it fails for the wrong reasons:
#announce
Scenario: Testing cucumber/aruba
Given a blank slate
Then the output from "ls -la" should contain "drw"
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[] (NoMethodError)
features/dataloader.feature:9:in `Then the output from "ls -la" should contain "drw"'
Anyone have any ideas why this isn't working? This seems to be very basic aruba behavior.
You are missing a 'When' step - the aruba "output should contain" step requires the command to have already run (it does not run it itself, it only looks it up).
#announce
Scenario: Testing cucumber/aruba
Given a blank slate
When I run `ls -la`
Then the output from "ls -la" should contain "drw"
This produces, on my machine:
#announce
Scenario: Testing cucumber/aruba # features/test_aruba.feature:8
When I run `ls -la` # aruba-0.4.11/lib/aruba/cucumber.rb:56
$ cd /Users/d.chetlin/dev/mine/ladder/tmp/aruba
$ ls -la
total 0
drwx------ 2 d.chetlin staff 68 Feb 15 23:38 .
drwx------ 7 d.chetlin staff 238 Feb 15 23:38 ..
Then the output from "ls -la" should contain "drw" # aruba-0.4.11/lib/aruba/cucumber.rb:86
1 scenario (1 passed)
2 steps (2 passed)
0m0.465s

system(): why do I not have the same permissions when using R in EMACS as I do in the bash terminal?

update: the error only occurs when logged into R from within emacs
what works:
When I ssh into a remote server and run
$ ./foo.rb
from the bash shell, it works. Furthermore, if I launch R and execute
$ R
system('./foo.rb')
I am in a group with permission to read/write/execute the file. File permissions are -rwxrwx---
what doesn't work:
Launch emacs and start an R session:
M-x R
ssh-myserver:.
system('./foo.rb')
I get the following error:
ruby: Permission denied -- foo.rb (LoadError)
why is this? Is there a way to work around this?
I can not find any information from ?system or ?system2
Here is the output from sessionInfo()
> sessionInfo()
R version 2.12.2 (2011-02-25)
Platform: x86_64-redhat-linux-gnu (64-bit)
locale:
[1] C
attached base packages:
[1] grid stats graphics grDevices utils datasets methods
[8] base
other attached packages:
[1] PECAn_0.1.1 xtable_1.5-6 gridExtra_0.7 RMySQL_0.7-5
[5] DBI_0.2-5 ggplot2_0.8.9 proto_0.3-8 reshape_0.8.3
[9] plyr_1.6 rjags_2.2.0-2 coda_0.13-5 lattice_0.19-17
[13] randtoolbox_1.09 rngWELL_0.9 MASS_7.3-11 XML_3.2-0
loaded via a namespace (and not attached):
[1] digest_0.4.2
Warning message:
'DESCRIPTION' file has 'Encoding' field and re-encoding is not possible
output of 'id' and 'env' from ssh and emacs, per comment by #sarnold (changed user names, group names, and ip addresses)
1. server
1.1 'id'
uid=1668(dleb) gid=1668(dleb) groups=117(ebusers),159(lab_admin),166(lab),1340(pal_web),1668(dleb)
1.2 'env'
LC_PAPER=en_US.UTF-8
LC_ADDRESS=en_US.UTF-8
LC_MONETARY=en_US.UTF-8
SHELL=/usr/local/bin/system-specific
KDE_NO_IPV6=1
SSH_CLIENT=888.888.888.88 51857 22
NCARG_FONTCAPS=/usr/lib64/ncarg/fontcaps
LC_NUMERIC=en_US.UTF-8
USER=dleb
LS_COLORS=
LC_TELEPHONE=en_US.UTF-8
KDEDIR=/usr
NCARG_GRAPHCAPS=/usr/lib64/ncarg/graphcaps
MAIL=/var/mail/dleb
PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/opt/dell/srvadmin/bin
LC_IDENTIFICATION=en_US.UTF-8
LC_COLLATE=en_US.UTF-8
R_LIBS=/home/a-m/dleb/lib/R
PWD=/home/dleb
NCARG_ROOT=/usr
KDE_IS_PRELINKED=1
LANG=en_US.UTF-8
NCARG_DATABASE=/usr/lib64/ncarg/database
MODULEPATH=/usr/share/Modules/modulefiles:/etc/modulefiles
LOADEDMODULES=
LC_MEASUREMENT=en_US.UTF-8
NCARG_LIB=/usr/lib64/ncarg
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
NCARG_NCARG=/usr/share/ncarg
SHLVL=1
HOME=/home/a-m/dleb
LOGNAME=dleb
CVS_RSH=ssh
SSH_CONNECTION=888.888.888.88 51857 999.999.999.99 22
LC_CTYPE=en_US.UTF-8
MODULESHOME=/usr/share/Modules
LESSOPEN=|/usr/bin/lesspipe.sh %s
DISPLAY=localhost:15.0
LC_TIME=en_US.UTF-8
G_BROKEN_FILENAMES=1
LC_NAME=en_US.UTF-8
_=/bin/env
emacs/ess R session
2.1 system('id')
uid=1668(dleb) gid=1668(dleb) groups=117(ebusers),159(lab_admin),166(lab),1340(pal_web),1668(dleb)
2.2 system('env')
LN_S=ln -s
R_TEXI2DVICMD=/usr/bin/texi2dvi
LC_PAPER=en_US.UTF-8
SED=/bin/sed
LC_ADDRESS=en_US.UTF-8
R_PDFVIEWER=/usr/bin/xdg-open
LC_MONETARY=en_US.UTF-8
HOSTNAME=ebi-forecast
R_INCLUDE_DIR=/usr/include/R
R_PRINTCMD=lpr
SHELL=/usr/local/bin/system-specific
TERM=dumb
AWK=gawk
HISTSIZE=1
R_RD4DVI=ae
SSH_CLIENT=888.888.888.88 51159 22
KDE_NO_IPV6=1
R_RD4PDF=times,hyper
R_PAPERSIZE=a4
NCARG_FONTCAPS=/usr/lib64/ncarg/fontcaps
PERL=/usr/bin/perl
LC_NUMERIC=en_US.UTF-8
SSH_TTY=/dev/pts/14
LC_ALL=C
EMACS=t
USER=dleb
LC_TELEPHONE=en_US.UTF-8
LS_COLORS=
LD_LIBRARY_PATH=/usr/lib64/R/lib:/usr/local/lib64:/usr/lib/jvm/jre/lib/amd64/server:/usr/lib/jvm/jre/lib/amd64:/usr/lib/jvm/java/lib/amd64:/usr/java/packages/lib/amd64:/lib:/usr/lib
TAR=/bin/gtar
ENV=
R_ZIPCMD=/usr/bin/zip
KDEDIR=/usr
PAGER=/usr/bin/less
NCARG_GRAPHCAPS=/usr/lib64/ncarg/graphcaps
R_GZIPCMD=/usr/bin/gzip
PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin
LC_COLLATE=en_US.UTF-8
LC_IDENTIFICATION=en_US.UTF-8
EGREP=/bin/grep -E
PWD=/home/a-m/dleb/pecan
INPUTRC=/etc/inputrc
R_LIBS=/home/a-m/dleb/lib/R
NCARG_ROOT=/usr
R_SHARE_DIR=/usr/share/R
WHICH=/usr/bin/which
EDITOR=vi
LANG=en_US.UTF-8
KDE_IS_PRELINKED=1
R_LIBS_SITE=/usr/local/lib/R/site-library:/usr/local/lib/R/library:/usr/lib64/R/library:/usr/share/R/library
M ODULEPATH=/usr/share/Modules/modulefiles:/etc/modulefiles
NCARG_DATABASE=/usr/lib64/ncarg/database
LC_MEASUREMENT=en_US.UTF-8
LOADEDMODULES=
PS3=
R_BROWSER=/usr/bin/xdg-open
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
NCARG_LIB=/usr/lib64/ncarg
HOME=/home/a-m/dleb
SHLVL=1
NCARG_NCARG=/usr/share/ncarg
R_ARCH=
TR=/usr/bin/tr
MAKE=make
R_UNZIPCMD=/usr/bin/unzip
LOGNAME=dleb
CVS_RSH=ssh
LC_CTYPE=en_US.UTF-8
SSH_CONNECTION=888.888.888.88 51159 999.999.999.99 22
R_BZIPCMD=/usr/bin/bzip2
MODULESHOME=/usr/share/Modules
LESSOPEN=|/usr/bin/lesspipe.sh %s
PROMPT_COMMAND=
R_HOME=/usr/lib64/R
DISPLAY=localhost:22.0
R_PLATFORM=x86_64-redhat-linux-gnu
INSIDE_EMACS=23.2.1,tramp:2.1.18-23.2
R_LIBS_USER=~/R/x86_64-redhat-linux-gnu-library/2.12
LC_TIME=en_US.UTF-8
R_DOC_DIR=/usr/share/doc/R-2.12.2
R_SESSION_TMPDIR=/tmp/RtmpqA6bpJ
HISTFILE=/home/a-m/dleb/.tramp_history
G_BROKEN_FILENAMES=1
LC_NAME=en_US.UTF-8
_=/bin/env
Assuming you started up R as the same user, you do. You error is not coming from a permissions problem for foo.rb, however, or else your shell would be giving the error. (i.e. sh: ./test.rb: Permission denied; see example below). Here, ruby itself is giving the error. Without knowing exactly what is in your foo.rb, I would suggest digging in there to see what it is trying to load/source, and checking the permissions on those.
#!/usr/bin/env ruby
puts 'Hello world'
Now in R....
> system('ls -l test.rb')
-rw-r--r-- 1 jcolby staff 40 Oct 21 08:23 test.rb
> system('./test.rb')
sh: ./test.rb: Permission denied
> system('chmod a+x test.rb')
> system('./test.rb')
Hello world
I presume the M ODULEPATH in the Emacs-derived output is simply a copy and paste typo.
The differences between the two env outputs is much greater than I expected; I've selected the ones that look slightly suspicious to me:
$ diff -u works fails
--- works 2011-10-24 15:04:02.000000000 -0700
+++ fails 2011-10-24 15:12:36.000000000 -0700
...
+LD_LIBRARY_PATH=/usr/lib64/R/lib:/usr/local/lib64:/usr/lib/jvm/jre/lib/amd64/server:/usr/lib/jvm/jre/lib/amd64:/usr/lib/jvm/java/lib/amd64:/usr/java/packages/lib/amd64:/lib:/usr/lib
...
-PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/opt/dell/srvadmin/bin
-PWD=/home/dleb
...
+PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin
...
+PWD=/home/a-m/dleb/pecan
...
In the emacs-derived session, your LD_LIBRARY_PATH environment variable may be changing specifics of which dynamically linked libraries are being used when executing ruby. If you ssh in to your server and execute your foo.rb with the changed LD_LIBRARY_PATH, does it work or fail?
LD_LIBRARY_PATH=/usr/lib64/R/lib:/usr/local/lib64:/usr/lib/jvm/jre/lib/amd64/server:/usr/lib/jvm/jre/lib/amd64:/usr/lib/jvm/java/lib/amd64:/usr/java/packages/lib/amd64:/lib:/usr/lib ./foo.rb
The PATH environment variable between the two sessions is different; perhaps you have permission to execute /usr/local/bin/ruby (or the libraries in /usr/local/lib/ruby/) but not /usr/bin/ruby (or the libraries in /usr/lib/ruby/). Does your script use #!env ruby or does it use #!/usr/bin/ruby (or some other fixed path)?
Your pwd in one instance is /home/dleb, the other /home/a-m/dleb/pecan -- but HOME is set to /home/a-m/dleb on both systems. Is /home/dleb a symbolic link or does it actually exist separate from /home/a-m/dleb? (This really is grasping at straws -- I don't think this is it, but this problem is baffling.)
One last thing to consider: is your server confined with a tool such as AppArmor, SELinux, TOMOYO, or SMACK? Any of these mandatory access control tools can prevent an application from writing in specific locations, perhaps they aren't yet configured for your site. Check dmesg(1) output to see if there are any rejection messages, most or all these tools log to dmesg(1) if auditd(8) isn't running.

Resources