Using gets() gives No such file or directory error when I pass arguments to my script
It looks like you want to the user to type some input by reading a line from STDIN
, the best way to do this is by calling STDIN.gets
and not gets
. So your line becomes:
word = STDIN.gets.chomp
This is documented as IO.gets
. STDIN
is an instance of IO
.
Right now, you're executing Kernel.gets
, which does something different (emphasis mine):
Returns (and assigns to $_) the next line from the list of files in ARGV (or $*), or from standard input if no files are present on the command line.
This appears to behave like STDIN.gets
if ARGV
is empty, but is not the same thing, hence the confusion.
Why is gets throwing an error when arguments are passed to my ruby script?
Ruby will automatically treat unparsed arguments as filenames, then open and read the files making the input available to ARGF
($<
). By default, gets
reads from ARGF. To bypass that:
$stdin.gets
It has been suggested that you could use STDIN
instead of $stdin
, but it's usually better to use $stdin
.
Additionally, after you capture the input you want from ARGV
, you can use:
ARGV.clear
Then you'll be free to gets
without it reading from files you may not have intended to read.
Python - Errno 2: No such file or directory
Never try to build your command name as a string.
In this particular case, be aware that single quotes have no protection effect on windows (unlike on Linux/Unix) which explains the quoting you've used is inefficient. Using double quotes would have worked, but it's not the best way.
Never use a string when you can pass the list of arguments. This will work:
subprocess.Popen(["python",r'\Users\Terra Byte\Desktop\jdos3\JDOS3\SYS64\bootthingy.py'])
- use list of strings, unquoted, and let
subprocess
do the work - remove
cmd /c
prefix, aspython
prefix is enough (alternately, removepython
to leave["cmd","/c"
and let file associations do the work) - use raw string prefix to avoid that backslashes are interpreted
How do I combine gets.chomp and ARGV in Ruby?
I answered a question about this yesterday, which you can read here, but to address your situation specifically:
After first, second, third = ARGV
, call ARGV.clear
to empty it out.
Alternatively you could do first, second, third = 3.times.map { ARGV.shift }
The reason is that gets
reads from ARGV if there's anything in it. You need to empty ARGV out before calling gets
.
Subprocess command shows FileNotFoundError: [Errno 2] No such file or directory
Your commands are still wrong. If you just want to run these commands like the shell does, the absolutely easiest way to do that is to ... use the shell.
result = subprocess.run('''
# useless cat, but bear with
cat output3.txt |
sed 's/"/ /g' |
grep "shipOption" |
grep -v "getShipMethod" |
cut -d ',' -f2 |
sed 's/"//g' |
sort |
uniq -c |
sort -nr |
head -10
''',
# Probably add these too
check=True,
capture_output=True,
# We are using the shell for piping etc
shell=True)
If you want to remove the shell=True
and manually run all these processes, you have to understand how the shell works. In particular, you need to fix the quoting so that the commands you run have the quotes which remain after the shell has processed the syntactic quotes.
p1 = subprocess.Popen(['cat', 'output3.txt'], stdout=subprocess.PIPE) # still useless
p2 = subprocess.Popen(['sed','s/"/ /g'], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(['grep', "shipOption"], stdin=p2.stdout,stdout=subprocess.PIPE)
p4 = subprocess.Popen(['grep', '-v', "getShipMethod"], stdin=p3.stdout, stdout=subprocess.PIPE)
p5 = subprocess.Popen(['cut', '-d', ',', '-f2'], stdin=p4.stdout, stdout=subprocess.PIPE)
p6 = subprocess.Popen(['sed', 's/"//g'],stdin=p5.stdout, stdout=subprocess.PIPE)
p7 = subprocess.Popen(['sort'], stdin=p6.stdout, stdout=subprocess.PIPE)
p8 = subprocess.Popen(['uniq', '-c'], stdin=p7.stdout, stdout=subprocess.PIPE)
p9 = subprocess.Popen(['sort', '-nr'], stdin=p8.stdout, stdout=subprocess.PIPE)
p0 = subprocess.Popen(['head', '-10'], stdin=p9.stdout, stdout=subprocess.PIPE)
Notice in particular how the arguments to sed
and grep
have their outer quotes removed, and how we removed shell=True
everywhere. As a rule of thumb, if the first argument to Popen
(or other subprocess
methods) is a list, you should not use shell=True
, and vice versa. (There are situations where you can pass a list to shell=True
but ... let's not even begin to go there.)
All of this seems rather moot, though, since Python can eminently well do all of these things.
from collections import Counter
counts = Counter()
with open('output3.txt', 'r', encoding='utf-8') as lines:
for line in lines:
line = line.rstrip('\n').replace('"', ' ')
if "shipOption" in line and "getShipMethod" not in line:
field = line.split(',')[1].replace('"', '')
counts[field] += 1
print(counts.most_common(10))
Probably you would want to put the rstrip
and replace
inside the if
to avoid unnecessary work. The same refactoring could be done to the shell pipeline, of course.
How to call an external script with arguments?
You almost figured it out, just add the params:
my_script = "script.sh"
%x( #{my_script} #{arg1} #{arg2})
You may also want to check the return code:
if $? == 0
puts "script executed successfully"
else
puts "script returned an error, exit code: #{$?.to_s.split('exit ')[-1]}"
end
How to call an external script with arguments?
You almost figured it out, just add the params:
my_script = "script.sh"
%x( #{my_script} #{arg1} #{arg2})
You may also want to check the return code:
if $? == 0
puts "script executed successfully"
else
puts "script returned an error, exit code: #{$?.to_s.split('exit ')[-1]}"
end
Can't pass filepath as function argument in vim
First, you don't need that colon in a scripting context:
function! MyFunc(fl)
!cat fl
endfunction
command! -nargs=1 RunFunc :call MyFunc(<f-args>)
Second, you can't pass an expressions like that. You need to concatenate the whole thing with :help :execute
:
function! MyFunc(fl)
execute "!cat " .. fl
endfunction
command! -nargs=1 RunFunc :call MyFunc(<f-args>)
Third, function arguments are typed with a:
:
function! MyFunc(fl)
execute "!cat " .. a:fl
endfunction
command! -nargs=1 RunFunc :call MyFunc(<f-args>)
As for websites… they are useless. Vim comes with an exhaustive documentation that should be your first hit when stumbling on something and it just so happens that the user manual—which is mandatory reading—has a whole chapter on writing vimscript: :help usr_41.txt
.
Passing arguments to system commands from perl
As the message says, you are passing the path to a non-existent file. Instead of passing
if0W211.jpg
you should be passing
/media/sf_Pictures_from_Reddit/if0W211.jpg
That still leaves you with the following problems:
- An injection bug
- Possible misinterpretation of the path as an option.
- A lack of error handling
- Lack of capture of the output of the program.
- Repeated executions of an external process.
All these can be fixed by using Image::Size instead.
But if you insist on using identify
,
use IPC::System::Simple qw( capturex );
my $dimensions = eval { capturex("identify", "-format", "%h,%w", "--", "$folder/$curPic") }
or do {
warn("Can't determine the dimensions of \"$folder/$curPic\": $@");
next;
};
my ($height, $width) = $dimensions =~ /^(\d+),(\d+)$/
or do {
warn("Can't determine the dimensions of \"$folder/$curPic\": Unexpected output from \"identify\": $dimensions\n");
next;
};
If your identify
doesn't support --
(or even if it does), you can replace
"--", "$folder/$curPic"
with
"$folder/$curPic" =~ s{^-}{./-}r
open() gives FileNotFoundError/IOError: Errno 2 No such file or directory
- Make sure the file exists: use
os.listdir()
to see the list of files in the current working directory - Make sure you're in the directory you think you're in with
os.getcwd()
(if you launch your code from an IDE, you may well be in a different directory) - You can then either:
- Call
os.chdir(dir)
,dir
being the folder where the file is
located, then open the file with just its name like you were doing. - Specify an absolute path to the file in your
open
call.
- Call
- Remember to use a raw string if your path uses backslashes, like
so:dir = r'C:\Python32'
- If you don't use raw-string, you have to escape every backslash:
'C:\\User\\Bob\\...'
- Forward-slashes also work on Windows
'C:/Python32'
and do not need to be escaped.
- If you don't use raw-string, you have to escape every backslash:
Let me clarify how Python finds files:
- An absolute path is a path that starts with your computer's root directory, for example
C:\Python\scripts
if you're on Windows. - A relative path is a path that does not start with your computer's root directory, and is instead relative to something called the working directory. You can view Python's current working directory by calling
os.getcwd()
.
If you try to do open('sortedLists.yaml')
, Python will see that you are passing it a relative path, so it will search for the file inside the current working directory.
Calling os.chdir()
will change the current working directory.
Example: Let's say file.txt
is found in C:\Folder
.
To open it, you can do:
os.chdir(r'C:\Folder')
open('file.txt') # relative path, looks inside the current working directory
or
open(r'C:\Folder\file.txt') # absolute path
Related Topics
How to Tell Rubocop to Ignore a Specific Directory or File
Ruby on Rails: How to Check If a File Is an Image
How to Split a String into Only Two Parts, by the Last Occurrence of the Split Char
Deleting a Hash from Array of Hashes in Ruby
Why Is Devise Not Displaying Authentication Errors on Sign in Page
Do You Check in Your Rvmrc File
Cannot Load Such File - Rubygems.Rb
Netbeans 6.9.1 + Rails 3 + Ruby 1.9.2P0 Debugging
Dynamically Define Named Classes in Ruby
Is It Acceptable Practice to Patch Ruby's Base Classes, Such as Fixnum
Convert String with Comma to Integer
How to Install 'Cocoapods' Gem from Rubygems.Org (Bad Response Backend Read Error)
If Else Statements in .Html.Erb in Views
Differencebetween "Be_True" and "Be True" in Rspec
How to Create Md5 Hash with Hmac Module in Ruby
What Is a Robust Installation Process for Nokogiri (On Ubuntu)