Right now I am using:
echo -ne '\n' | alternatives --config java
For
Enter to keep the current selection, or type selection number:
I know there are probably many ways to do this. I am looking for the correct way to perform this action. I honestly don't even know if I'm doing it right.
Probably you could use something less interactive.
alternatives --set java /your/favorite/version
should work.
Or you can use 'expect' command to emulate user input.
Related
su
Enter Password: abcd
I need to be able to do the above process through a shell script. The issue is that it needs to be done with only the basic set of libraries that are available. No additional libraries can be used (eg except). Kindly do not suggest the usage of "sudo" or other things, this is the exact thing I need to do.
I have tried the following:
echo "abcd" | su
But it still ends up asking for the password again.
You should try NOPASSWD option. Use it for the particular command which you are going to execute for security reasons. Here are two methods explained but i think second one is what exactly you need.
I wrote a script for resizing windows, which require orientation and value in form of fraction, like so:
resize.sh -h 1/2
and it works as expected.
I also added -k flag, which means that script require user input, like so:
resize.sh -k -h
and in the script:
read -rsn 2 fraction
which I parse to get values for numerator and denominator.
This works great from command line, but idea behind this is to bind resize.sh -k -h to some key combination, and pass following two keys as input. But when I run script from keyboard, it run as a background process which is not associated with any tty, so read could not get its input. Is there any way to redirect global input to background process, after running it from keyboard.
What I tried so far:
Redirection to /proc/$$/fd/0, which didn't work.
Redirectiong currently active tty stdin to read, like so:
read -rsn 2 fraction < /dev/pts/0
which actually worked, but problem is that not all windows are terminal, e.g. web browser.
If my question is unclear, please feel free to ask for additional clarifications or details, and thanks in advance :)
You can use a named pipe for the process communication.
I made am example script where the background proces is a function.
#!/bin/bash
pipe_name=/tmp/mypipe$$
mkfifo "${pipe_name}"
resize()
{
read fraction < "${pipe_name}"
echo "Resize window to fraction=${fraction}"
}
resize &
read -p "Enter your fraction: "
echo "${REPLY}" > "${pipe_name}"
rm "${pipe_name}"
thank you both for providing very useful information. The solution is combination of both, actually.
First I modified read command in resize.sh to get input from named pipe, as Walter suggested, than I wrote a new, kinda "wrapper" script, which executes resize.sh in background, and than, since Barmar pointed I need a gui window, it starts very small terminal window running read and passing input to named pipe. Further more, using wmctrl I manage to place small terminal window right where currently active window begins, and hide it below (thanks to openbox per-application properties), so it's technically not visible at all :)
It's really too hacky for my liking, but it was really the only option I could think of at this moment, so until I find the better way, this gets the job done.
Once again, thank you both for directing me toward solution, I really appreciate it, cheers :)
I'm teaching an introductory Linux course and have abandoned the paper-based multiple-choice quizzes and have created interactive quizzes in Bash. My quiz script is functional, but kind of quick-and-dirty, and now I'm in the improvement phase and looking for suggestions.
First off, I'm not looking to automate the grading, which certainly simplifies things.
Currently, I have a different script file for each quiz, and the questions are hard-coded. That's obviously terrible, so I created a .txt file holding the questions, delimited by lines with "question 01" etc. I can loop through and use sed -n "/^quest.*$i\$/,/^quest.*$(($i+1))\$/p", but this prints the delimiter lines. I can pipe through sed "/^q/d" or head -n-1|tail -n+2 to get rid of them, but is there a better way?
Second issue: For questions where the answer is an actual command, I'm printing a [user]$ prompt, but for short-answer, I'm using a >. In my text file, for each question, the last line is the prompt to use. Initially, I was thinking I could store the question in a variable and |tail -1 it to get the prompt, but duh, when you store it it strips newlines. I want the cursor to immediately follow the prompt, so I either need to pass it to read -p or strip the final newline from the output. (Or create some marker in the file to differentiate between the $ and > prompt.) One thought I had was to store each question in a separate file and just cat it to display it, making sure there was no newline at the end. That might be kind of a pain to maintain, but it would solve both problems. Thoughts?
Now to how I'm actually running the quiz. This is a Fedora 20 box, and I tried copying bash and setuid-ing it to me so that it would be able to read the quiz script that the students couldn't normally read, but I couldn't get that to work. After some trial and error, I ended up copying touch and setuid-ing it to me, then using that to create their answer file in a "submit" directory with an ACL so new files have o=w so they can write to their answer file (in the quiz with >> echo) but not read it back or access the directory. The only major loophole I see with this is that they can delete their file by name and start the quiz over with no record of having done so. Since I'm not doing any automatic grading, I'm not terribly concerned with the students being able to read the script file, although if I'm storing the questions separately, I suppose I could make a copy of cat and setuid it to read in files that they can't access.
Also, I realize that Bash is not the best choice for this, and learning the required simple input/output for Python or something better would not take much effort. Perhaps that's my next step.
1) You could use
sed -n "/^quest.*$i\$/,/^quest.*$(($i+1))\$/ { //!p }"
Here // repeats the last attempted pattern, which is the opening pattern in the first line of the range and the closing pattern for the rest.
...by the way, if you really want to do this with sed, you better be damn sure that i is a number, or you'll run into code injection problems.
2) You can store multiline command output in a variable without problems. You just have to make sure you quote the variable everafter to avoid shell expansion on it. For example,
QUESTION=$(sed -n "/^quest.*$i\$/,/^quest.*$(($i+1))\$/ { //!p }" questions.txt)
echo -n "$QUESTION" # <-- the double quotes are important here.
The -n option to echo tells echo to not append a newline at the end, which should take care of your prompt problem.
3) Yes, well, hackery breeds more hackery. If you want to lock this down, the first order of business would be to not give students a shell on the test machine. You could put your script behind inetd and have the students fill it out with telnet or something, I suppose, but...really, why bash? If it were me, I'd knock something together with a web server and one of the several gazillion php web quiz frameworks. Although I also have to wonder why it's a problem if students can see the questions and the answers they gave. It's not like all students use the same account and can see each other's answers, is it? (is it?) Don't store an answer key on the same machine and you shouldn't have a problem.
I've written a script (that doesn't work) that looks something like this:
#!/bin/sh
screen -dmS "somename" $HOME/somescript.sh
j=13
for i in {0..5}; do
screen -dmS "name$i" $HOME/anotherscript.sh $i $j
j=10
done
If I copy and paste this into a terminal, it creates 7 detached screen sessions, as I expect. If I run it from within a script, however, I get only the first session, "somename," when I run screen -ls.
I realize screen can be used to create multiple windows within one session. It doesn't really matter to me how these scripts get run. I just want to get to the bottom of why this doesn't work as a script.
Note: I've asked this question on SuperUser without any suitable responses. I figured maybe that's the wrong place to ask what could be considered a programming question.
One thing you might be getting bitten on is which specific version of which specific shell you're running. /bin/sh could actually be bash, or it could be bourne, and that can make a difference on how your loop syntax is interpreted. The {0..5} construct isn't understood in older versions of bash (v2.x), for instance, nor in bourne (at least it wasn't when I finally managed to track down a /bin/sh that was a real, live bourne shell :-).
My suggestion is to change your shebang line to /bin/bash if you need its syntax, and check that your bash is version 3.x or later. Since you say it works from the commandline, my bet is on the shebang line, though.
I like to keep my shell sessions named with useful titles as I work, this helps me keep track of what I'm using each of the many tabs for.
Currently to rename a session I double click its name on the tabbed part of the console - is there any command that I can use to do this from within the shell? It would save me a bit of time.
thanks in advance
edit :-
I am using KDE's Konsole shell.
The article How to change the title of an xterm should help.
Currently to rename a session I double click its name on the tabbed part of the console
This sounds like you're using KDE's Konsole. Is this true?
If so, in KDE 3:
dcop $KONSOLE_DCOP_SESSION renameSession "I am renamed!"
In KDE 4, the old DCOP interfaces haven't been ported over to the new D-BUS IPC yet, but you can change the settings for tabnames to follow the window name set by each screen, and set the window name as described by the other answers.
According to this page, you should be able to use something like this:
echo -n "\033]0;New Window Title\007"
I'm not in Linux at the moment, so this is untested. I do know that it is possible to change the window title under program control, so this seems likely to work.
For /usr/bin/konsole
you can change the title of a konsole terminal from the menu:
Settings->Edit Current Profile->Tabs
edit "Tab title format" to be whatever you want. After interacting with the shell, the title will reset to what you put.
for /usr/bin/xterm running in xorg-server 2:1.10.1-1ubuntu1
echo -ne "\033]0;My Fun X-Terminal\007"
The answer to this really depends on the terminal program you're using.
However, I'll just assume it's sensible, and emulates an xterm enough that it respects xterm escape codes - in which case, you probably want to look here : http://www.faqs.org/docs/Linux-mini/Xterm-Title.html#s3
Note: unwind's example below requires echo to be called like this "echo -ne", otherwise the '\' characters are echoed literally.
For the default terminal on Ubuntu (I'm still on 10.04) try xtitle.
$> sudo apt-get install xtitle
...
$> xtitle --title wow it worked!
or simply
$> xtitle this is great