Erroneously using STDIN when pasting a script into the Terminal.app - ruby

I have the following script-snipped, which I use regularly to semi-automate one of my workflows.
I open a bash terminal and start irb and then paste the script:
require 'highline/import'
# ...
user = ask("User:")
repo = ask("Repository:")
# ...
# Do advanced fancy stuff
Now I want to be able to paste this into the terminal, but the first prompt for the user is overwritten by the following line: repo = ask("Repository:").
Is there a way to prevent this behaviour.
I know that I could write a script. But
I find it convenient to be able to just paste this into the terminal
I wonder how the STDIN can be somehow outfoxed in this case

Is there a way to prevent this behaviour.
You can prevent the echoing of pasted text with the command
stty -echo
- whether you like that is another question, since this inevitably also prevents the echoing of typed-in commands, but you can see again after entering
stty echo

Related

Bash script that creates a command, then stores it in user's history, so they can just press up, to edit the command before running it?

I have a script that generates a command and prints it to stdout. Fairly simple.
I want to put that command in the user's bash history, so they can just press UP on their keyboard to get access to it, to edit the command. Is this possible? how can I do this?
I tried doing the following
history -s "ls -la"
echo "ls -la" >> ~/.bash_history
The first one did not work. and the second command put the desired command in the users bash history, but typing history did not show the command. I even tried using history -w and that did not work either.
If I am going about this the wrong way let me know, maybe there is another way to do this.

Is there any way to come back to a ready-to-enter command in fish shell by just pressing a combination of keys?

Some times that I have a command ready to press enter but that command I have changed it in some way and it's a long command, then I remember that I have to open a text file (e.g. to get some information that I will use in the command). So what most of the times I do, is to cancel that command (Ctrl+C) and then open the text file get the information I need and then retype the command again with the pasted value from the text file. This is not very efficient for me specially if the server doesn't have any kind of GUI and I can't copy the previous command so I don't lose it.
So my question is, Is there any kind of combination keys that I could use to save a command ready to enter so I don't lose it and I don't have to type it all over again?
Thanks!
This is currently not possible out of the box.
The easiest way to do it is probably to
Change the cancel binding to stash the commandline
Add a binding to recall the stashed commandline
It would work something like this:
The function to recall:
function recall_commandline
if set -q stashed_commandline
commandline -r -- $stashed_commandline
end
end
Add to __fish_cancel_commandline (use funced __fish_cancel_commandline. Once you are happy do funcsave __fish_cancel_commandline):
set -g stashed_commandline $cmd
# right before:
commandline ""
Add to fish_user_key_bindings
bind \cr recall_commandline
This will allow you to press Ctrl+r to recall the last cancelled commandline. Expanding it to multiple is non-trivial (since "commandlines" can have multiple lines), as is adding the commandlines to history so that they can be recalled with the normal bindings.
I have the following function to turn comment/uncomment the current statement:
function toggle-comment-cmd-buffer --description 'Comment/Uncomment the current or every line'
set -l cmdlines (commandline -b)
if test "$cmdlines" = ""
return
end
set -l cmdlines (printf '%s\n' '#'$cmdlines | string replace -r '^##' '')
commandline -r $cmdlines
string match -q '#*' $cmdlines[1]; and commandline -f execute
end
I bind it thusly: bind \e\# toggle-comment-cmd-buffer. This way I can quickly comment and put the current statement in my command history in order to do something else. Then I can recall the comment and press [alt-#] again to remove the comment characters and continue modifying the command.
I set this up in my personal fish config because I had gotten used to doing something similar in ksh93.

Bash script calls vi for manual editing, then script resumes?

I wrote a script that creates a backup of a text file, and a second script that verifies some syntax in text file using SED.
In the middle, there is a manual process: Users edit the original file adding some strings. This process must remain manual.
I would like to merge my two scripts so the backup is created, vi is open for the user, when the user is done editing the file, the script resumes doing the syntax verification.
I am learning by doing, but really do not know how to code the "open vi, wait for the user to do his editing, take control over and resume with verification" part.
I read there is a function called system (in Perl) that could be used, but my code is in BASH.
Any suggestions on how to get this done in BASH? Thanks!
In bash, each statement is essentially like an implicit call to system (unless it's a builtin shell command) since shell scripts are designed to make it easy to run other programs.
backup some_file.txt
vi some_file.txt # The script blocks until the user exits vi
verify_syntax some_file.txt
The only difference between using vi and a command like ls is that ls will do its thing and exit without user intervention, while vi (or any interactive command) will run until the user explicitly exits.

can the shell be told to save command output?

I'm thinking a hypothetical CMDOUTPUT would be useful:
locate -r 'regexp...' # locate finds a file: /myfile.
# Shell puts `/myfile' string into CMDOUTPUT
vim $CMDOUTPUT # No need to run locate again as with: vim `!!`
The locate command above is just an example. I want the output saved for all commands that I run so that if I need it I can access it quickly. (The output should still be printed by the command to stdout.) I don't want to do
CMDOUTPUT="$(...)"
or
command | tee /tmp/cmdoutput
or anything else that I have to do because that's more typing for me at the prompt for everything that I run: I want the shell to do it all in the background. Again, to make it clear: I am casually typing commands away and decide "Oh, I want to use the output of that last command in this command, let me just retrieve it...". Can I tell the shell to store the output somehow so that I can retrieve it.
If there's no option for it, is there some way that I can implement it that is as close to invisible as it can be, meaning exit codes from the command are not lost (...and that's all I can think of, but I'm sure there are other subtleties) etc. I'm primarily thinking of zsh, but answers for any shell would be useful.
I found a solution, not sure if this is exactly what you're looking for. But it should provide a start :)
zsh | tee log >&1

Open Vim from a Rakefile?

I am creating a journal application for personal notes and have the following in my Rakefile:
task :new do
entry_name = "Entries/#{Time.now.to_s.gsub(/[-\ :]+/, '.').gsub(/.0500+/,'')}.md"
`touch #{entry_name}`
`echo "# $(date)" >> #{entry_name}`
end
The last part I would like to include is the opening of the Vim text editor but I am unable to figure out how to open it as if I called it directly from the bash terminal.
I have tried:
vim #{entry_name}
but unfortunately I think both of those open it as a background process.
I have been referencing "6 Ways to Run Shell Commands in Ruby".
As in the article you referenced, `s run the command in a subshell within the current process, but the real problem is that it's trying to take the output from the command run as well, which doesn't play nice with Vim.
You can either:
Use exec to replace the current process with the new one (note that the Ruby/Rake process will end once you've called exec, and nothing after it will run).
Use system to create a subshell like `s, but avoids the problem of trying to grab Vim's stdout. Unlike exec, after Vim terminates, Ruby will continue.
you need to pass the tty as standard input for backspaces etc. to work well in vim:
exec("</dev/tty vim a b")
obviously the backtick (`) didn't work but I was having issues with system/exec from a script.
first I get Vim: Warning: Input is not from a terminal, and then I see ^? when I use backspace.

Resources