I want to create a bash script that is simular to a programming interpreter like mongo, node, redis-cli, mysql, etc.
I want to be able to use a command like test and it behave like the examples above.
thomas#workstation:~$ test
>
How do I make a command that behaves like this? What is this called?
I want to be able to take the content and turn it into a variable.
thomas#workstation:~$ test
> hello world
hello world
thomas#workstation:~$
I only want to take one "entry" after enter is pressed once I want to be able to process the string "hello world" in the code, like echo it.
What is this called? How do I make one using BASH?
I think "read" is what you are looking for, isn't it?
here is a link with some examples: http://bash.cyberciti.biz/guide/Getting_User_Input_Via_Keyboard
so you can do stuff like this:
read -p "Enter your name : " name
echo "Hi, $name. Let us be friends!"
I'm sorry this doesn't answer you directly, but it might be worth it to look into using a more fully capable programming language such as Python, Ruby, or Perl for a task like this. In Python you can use the raw_input() function.
user_command = raw_input('> ')
would yield your prompt.
First, do not name your script test. That generates too much confusion. Whatever you call it, you can do many things:
#!/bin/sh
printf '> '
read line
echo "$line"
If your shell supports it:
#!/bin/sh
read -p '> ' line
echo "$line"
or
#!/bin/sh
printf '> '
sed 1q # This will print the input. To store in in a variable: a=$( sed 1q )
[spatel#tux ~]$ read a
Hello World!!!!!
[spatel#tux ~]$ echo $a
Hello World!!!!!
Key word that might be useful here is REPL (Read–eval–print loop) used primarily for programming languages or coding environments. Your browsers console is a great example of a REPL.
Node allows you use their REPL to build interactive apps.
Related
I want to use a command to be printed on the same line as the string.
for example, i want to print something like:
hostname: cpu1
but when i use the command like this it doesnt work
echo 'hostname:' hostname
You need to use $() to evaluate:
echo 'hostname:' $(hostname)
Two answers are already given saying that you "need to" and "should" use command substitution by doing:
echo "hostname: $(hostname)"
but I will disagree with both. Although that works, it is aesthetically unappealing. That command instructs the shell to run hostname and read its output, and then pass that output as part of the argument to echo. But all that work is unnecessary. For this simple use case, it is "simpler" to do:
printf "hostname: "; hostname
(Using printf to suppress the newline, and avoiding echo -n because echo really should be treated as deprecated). This way, the output of hostname goes directly to the shell's stdout without any additional work being done by the shell. I put "simpler" in quotes because an argument could be made that humans find printf "hostname: %s\n" "$(hostname)" or echo "hostname: $(hostname)" to be simpler, and perhaps looking at much code that does things that way warps your mind and even makes it look simpler, but a few moments reflection should reveal that indeed it is not.
OTOH, there are valid reasons for collecting the output and writing the message with echo/printf. In particular, by doing it that way, the message will (most likely) be written with one system call and not be subject to interleaving with messages from other processes. If you printf first and then execute hostname, other processes' data may get written between the output of printf and the output of hostname. As always, YMMV.
This is what you should do:
echo "hostname: `hostname`"
Words enclosed in backticks are read by the command line as commands even when they are inside a string, like in this case.
Have a great day! :)
I'm working on a bash script that will add users in a batch process. This code goes as follows:
#!/bin/bash
# A script that creates users.
echo "This is a script to create new users on this system."
echo "How many users do you want to add?"
read am
echo " "
for i in {0..$am..1}
do
echo "Enter a username below:"
read usern
sudo useradd $usern
sudo passwd $usern
echo " "
echo "User $am '$usern' added."
done
In this case, I wanted to make 4 users. I went through and entered the username "callum3" and set the password as "1234" for ease of login. Once I input everything (correctly, may I add) the terminal window displays the following.
User 4 'callum3' added.
This shows that my for loop isn't actually working, when I can see nothing wrong with it. I have tried using a while loop with no luck there either.
Am I making a rookie mistake here or is there something deeper going on?
Although I suspected it, for a better understanding on what could be wrong with your script I pasted it in shellcheck.net. That the problem is in the line:
for i in {0..$am..1}
Bash doesn't support variables in brace range expansions. That is, you cannot use a variable in an expression like {..}.
Instead, use seq. With seq $var you get a sequence from 1 (default) to $var:
for i in $(seq "$am")
I feel like I'm missing something in that nobody has suggested an arithmetic for loop:
for ((i=0; i<am; i++)); do
…
done
This has the particular benefit in bash of being both readable and not requiring a subshell.
You can use:
for i in `seq 0 $((am-1))`
do
...
done
Sequence will start from 0 and end at $am-1
Is it possible to output text to a shell window, via bash script, that is user-editable? I essentially want to pre-fill certain information and give the user the ability to edit it if it's wrong.
For instance, if I were to write in a script:
echo -n "Enter your name: Anthony"
while read user_input
do
# do stuff with $user_input
done
How can I allow the user to inline edit the word Anthony only (aka, don't allow backspacing past the A in Anthony), and how can I store the value into a variable once the RETURN key is pressed?
EDIT
I'm looking for something similar to the -i option of read (see answer posted here), but this is only available on bash 4+. Is there an alternative for bash 3?
I needed similar setup recently so what I did was
$ cat a.sh
function input {
python -c '
import sys,readline
readline.set_startup_hook(lambda: readline.insert_text(sys.argv[2]))
sys.stderr.write(raw_input(sys.argv[1]))
' "$#" 3>&1 1>&2 2>&3
}
A=$( input 'question: ' default )
echo "A='$A'"
$ ./a.sh
question: default
A='default'
Well, it's not actually bash, but it made the job done.
If I run a bash script as
./myscript.sh zone=A build=release
Is there someway I can read the arguments based on the parameters instead of using $1, $2?
No. Unix shells are an ancient technology, hash maps were known at the time but not "en vogue." They needed more than 1 byte to implement so the professionals didn't want to use such a wasteful technology.
What else can you do? The usual solution is getopt(1).
An alternative is to write all options to a file and source that:
echo "$#" | tr ' ' '\n' > options
. ./options
echo "zone=${zone}"
Hope this is what you are asking for:
A="try"
try="something"
echo ${!A}
> something
This is close to what you want.
set -k
./myscript.sh zone=A build=release
will behave the same as
zone=A build=release ./myscript.sh
that is, myscript.sh will see zone and build with the given values in its environment.
How can I store the result of an an expression into a variable?
echo "hello" > var1
Can I also do something like this?
var1.substring(10,15);
var1.replace('hello', '2');
var1.indexof('hello')
PS. I had tried Googling, but was not sucessful.
As #larsmans comments, Konsole is the terminal emulator, which in turn runs a shell.
On linux, this is typically bash, but it could be something else.
Find out what shell you're using, and print the man page.
echo $SHELL # shows the full path to the shell
man ${SHELL##*/} # use the rightmost part (typically bash, in linux)
For a general introduction, use the wikipedia entry on the unix shell or the GNU Bash refererence
Some specific answers:
var1="hello"
echo ${var1:0:4} # prints "hell"
echo ${var1/hello/2} # prints "2" -- replace "hello" with "2"
And at the risk of showing off:
index_of() { (t=${1%%$2*} && echo ${#t}); } # define function index_of
index_of "I say hello" hello
6
But this goes beyond simple shell programming.
Konsole is bash basically. So its technically bash that you are looking for.
Suppose:
s="hello"
For var1.substring(1,3);
you would do:
$ echo ${s:1:2}
el
For var1.replace('e', 'u');
you can:
$ echo ${s/l/u} #replace only the first instance.
hullo
$ echo ${s//e/u} #this will replace all instances of e with u
For var1.indexof('l')
You can (I dont know of any bash-ish method but, anyway):
$ echo $(expr index hello l)
4
In bash (the standard shell on linux) the syntax for storing the result of an expression in a variable is
VAR=$( EXPRESSION )
so, for example:
$ var=$(echo "hello")
$ echo $var
hello
For your second question: yes, these kind of things are possible using only the shell - but you're probably better of using a scripting language like python.
For what its worth: Here is a document describing how to do string manipulations in bash.
As you can see, it's not exactly beautiful.