[interactor] workspace-test > run file.read /Users/mycomputer/Desktop/test.txt
:enoent
[interactor] workspace-test >
Above is what I get when I run file.read logic.
Q1. What does the error message :enoent mean?
Q2. How can I check whether Interactor has read the file?
:enoent stands for "error no entity" which means that the file does not exist. You may want to double check that you got the file path correct.
You can also use the file.exist function to handle non-existing files in your logic. For example:
service read : map
# 1: file_path
on start : if (file.exist $1) (file.read $1) (event error)
on error : list
error = 'File does not exist: $1'
log 'service.read.error' $error
throw $error
exit
exit
Related
I have a Setup that doesn't work at the moment:
Lets say I have a program.sh
source path/service_x.sh; install_service_x || error_exit
source path/service_y.sh; install_service_y || error_exit
[...]
A service_y.sh with the function install_service_y
install_service_y()
{
[doing funny stuff that likes to fail ;)]
}
An error.sh
with the function error_exit inside which is doing many stuff.
Example:
error_exit()
{
echo "{$error}"
[...]
echo "Here are the error Logs. Error: {$error} appeared" | mutt -a "a_log_file" -s "failed to install service" -- error#yxz.com
}
So, I'm running the program.sh and install_service_y fails,
I want to have that error message stored to a variable $error to use it in the error_exit function of the error.sh
I really hope that you can understand my setup and whats going wrong.
So I read the easiest way to use .conf files for bash scripts is to use source to load such files. Now, what if I want to edit this file ?
Some code I found does a really good job :
function set_config(){
sed -i "s/^\($1\s*=\s*\).*\$/\1$2/" $conf_file
}
But, if the variable is not yet defined, it doesn't define it, nor does it check if the parameters are passed well, isn't secure, doesn't handle default values etc...
Does reliable tools/code already exists to edit .conf file which contain key="value" pairs ? For instance, I would like to be able to do things like this :
$conf_file="my_script.conf"
conf_load $conf_file #should create the file if it doesn't exist !
read=$(conf_get_value "data" "default_value") #should read the value with key "data", defaulting to "default_value"
if [[ $? = 0 ]] #we should be able to know if the read was successful
then
echo "Successfully read value for field \"data\" : $read"
else
echo "Default value for field \"data\" : $read"
fi
conf_set "something_new" "a great value!" #should add the key "something_new" as it doesn't exist
conf_set "data" "new_value" #should edit the value with key "data"
if [[ $? = 0 ]]
then
echo "Edit successful !"
else #something went wrong :-/
echo "Edit failed !"
fi
before running this code, the conf file would contain
data="some_value"
and after it would be
data="new_value"
something_new="a great value!"
and the code should output
Successfully read value for field "data" : some_value
Edit successful !
I am using bash version 4.3.30 .
Thanks for your help.
I'd to that with awk since it's rather good at tokenizing:
# overwrite config's entries for KEY with VALUE or else appends the definition
# Usage: set_config KEY VALUE
set_config() {
[ -n "$1" ] && awk -F= -v key="$1" -v new="$1=\"$2\"" '
$1 == key { $0 = new; key_found = 1; }
{ print }
END { if (!key_found) { print new; }
' "$conf_file" > "$conf_file.new" \
&& cat "$conf_file.new" > "$conf_file" && rm "$conf_file.new"
}
If run without arguments, set_config() will do nothing and return false. If run with only one argument, it will create an empty value (outputting KEY="").
The awk command parses the .conf file line by line, looking for each definition of the given key and altering it to the new value. All lines are then printed (with or without modification), preserving the original order. If the key hasn't yet been found by the end of the file, this appends the new definition.
Because you can't pipe a file atop itself, this gets saved with a ".new" extension and then copied atop the original in a manner that preserves permissions. The ".new" copy is then removed. I used && to ensure that these never happen if an error occurred earlier in the function.
Also note that the type of ".conf file" you're referring to (the type you source with a POSIX shell) will never have spaces around its equals signs, so the \s* parts of your sed command aren't needed.
The program should write "File Empty" if the file is empty; otherwise, it should write "File Full". Here's what I have so far:
fname = "fileTest.txt"
somefile = File.open(fname, "w")
if File.readlines(somefile).grep(/monitor/).size == 0
somefile.write("File Empty")
else
somefile.write("File Full.")
end
somefile.close
When I run this the first time, fileText.txt is empty, so the program writes "File Empty". When I run it a second time, the program should write "File Full", but the file still reads "File Empty".
The if statement should be checking if the file is empty, but I don't it is working correctly. What am I doing wrong?
EDIT - Problem Solved:
fname = "fileTest.txt"
somefile = File.open(fname, "a")
if File.zero?(somefile)
somefile.write("File Empty")
else
somefile.write("File Full.")
end
somefile.close
The "w" option in File.open(fname,"w") truncates the file if it exists or creates a new file if it does not exists- it will always be empty opened in this mode . See here for the options.
File.readlines does not need a file object, a string ("path/to/filename.txt"), or in this case fname will do.
Your code doesn't really match your question.
You say:
The program should write "File Empty" if the file is empty; otherwise,
it should write "File Full"
But you code says this:
if File.readlines(somefile).grep(/monitor/).size == 0
somefile.write("File Empty")
else
somefile.write("File Full.")
end
You are grepping for an RE that matches monitor and, if you don't find it, you're code says to write "File Empty".
"File Empty" does not contain "monitor", so when the program is run a second time, it once again reports "file empty"
If you are actually trying to solve the problem I quoted, then you can use File.zero?("filename") as a quick and easy solution.
Why do i get this error 'ruby: No such file or directory -- Readingfile.rb (LoadError)' when i run my ruby program to read files?
My code:
filename = ARGV.first
txt = open(filename)
puts "Heres your file#{filename}:"
print txt.read
print "TYpe the filename again"
file_again = $stdin.gets.chomp
txt_again = open(file_again)
print txt_again.read
'ruby: No such file or directory -- Readingfile.rb (LoadError)'
Without a stack trace, I can only infer that this error originates from the line txt = open(filename). What's most likely is that the filename (first arg passed into $ ruby file.rb) either does not exist or was unspecified (and therefore nil).
In order to ensure that your program is resilient to different kinds of input, you should check and handle cases where no valid filename is passed. This can be done with File#exist?:
puts "Missing filename" and exit! unless filename = ARGV.first
Hey so I have a bash command that echos a string based on reading some file. Say for simplicity it is like this
for line in `cat file`
do
if [ "$line" == "IwantThisLine" ]
then
echo "True"
fi
done
And I have it saved as its own individual script. Its called readRef.sh. So now I want to call it in matlab and store whatever it outputs in a variable! I am not entirely sure on how to do that, I seem to get an error when using evalc() on a system(). But it could be just me messing up quotations.
I tried something like
evalc(system(['./readRef.sh ' bamfile']))
The "bamfile" is a variable that is just a string to the path of a bamfile.
I get this error.
>> tes = evalc(system(['./readRef.sh ' smplBamFile]))
hg18
??? Undefined function or method 'evalc' for input arguments of type 'double'.
Coincidentally it does spit out "hg18" which is what I want to set the matlab variable to be.
Oh, I see. I don't think you need evalc at all. Reading the system docs you can just do:
[status, result] = system('echo True; echo "I got a loverly bunch of coconuts"')
And result will be
True
I got a loverly bunch of coconuts
So just do:
[status, result] = system(['./readRef.sh ' smplBamFile])
The reason evalc isn't working is that it requires its input to be a Matlab expression in a string, but you are passing it the result of system.
You could try:
evalc("system(['./readRef.sh ' smplBamFile])")
See how I'm passing in the system(...) as a string?
The reason you get this error is because system(...) returns the return-code of the command it ran, not its output. To capture its output, use
[~, output] = system(...)
tes = evalc(output);