Using Gets() Gives "No Such File or Directory" Error When I Pass Arguments to My Script

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, as python prefix is enough (alternately, remove python 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.
  • 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.

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



Leave a reply



Submit