I created a bash script :
#!/bin/bash
su root -c vim $1 -c ':%s/^M//g' -c 'wq'
My script has to remove all the ^M (carriage return on Windows) on my file, then save it.
When I execute my script it returns :
/sequenceFiles/Sequence1.seq: wq: command not found
Does someone know why ?
Thanks for your help.
The -c is seen by su, not vim, and the shell complains about the unknown command.
You need to pass the command as one argument to su:
su root -c "vim $1 -c ':%s/^M//g' -c 'wq'"
man su says:
`-c COMMAND'
`--command=COMMAND'
Pass COMMAND, a single command line to run, to the shell with a
`-c' option instead of starting an interactive shell.
Try
su root -c "vim $1 -c ':%s/^M//g' -c 'wq'"
While you can do it with vim, consider simpler:
perl -pi -e 's/\r\n/\n/' file
Related
Could you please clarify on the use of -l option of exec shell command. I didn't notice any difference when I ran exec ls | cat and exec -l ls | cat.
The -l option of exec adds a - at the beginning of the name of your command. For example:
exec -l diff | head
-diff: missing operand after '-diff'
-diff: Try '-diff --help' for more information.
Note the - everywhere before diff.
The point of all this? If you have a - before a command to start a shell it will act as a login shell. From man bash:
A login shell is one whose first character of argument zero is a -, or one started with the --login option.
Now, man exec states that:
If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is
what login(1) does.
So exec -l bash will run bash as a login shell. To test this, we can use the fact that a login bash executes the file ~/.bash_profile, so:
$ cat ~/.bash_profile
#!/bin/sh
printf "I am a login shell!\n"
If I start a login bash, the command printf "I am a login shell!\n" will be executed. Now to test with exec:
$ exec bash
$
Nothing is displayed, we are on a non-login shell.
$ exec -l bash
I am a login shell!
$
Here we have a login shell.
I would like to connect to a remote server with the smbclient command and pass some arguments to the script.
Here is my command:
smbclient //$SERVER -c 'cd $PATH;get $FILE /tmp/$FILE' $PASS -U$PSEUDO -W domain
When I launch this command without variables on the command line it works. But when I use it in the script it says:
./test1.sh: line 14: smbclient: command not found
Why is that?
Here is my complete script with for exemple arguments testSRV, testPATH and testFile :
\#! /bin/bash
SERVEUR=$1
PATH=$2
FILE=$3
echo $PATH #Return testPATH
echo $FILE #Return testFILE
\#COMPLETEPATH="cd $testPATH;get $testFILE /tmp/$testFILE"
\#echo $COMPLETEPATH //return
/usr/bin/smbclient //$SERVER -c 'cd $PATH;get $FILE' testpassword -U testuser -W testdomain
It's good,
Thanks you all but I achieved to make my script works.
I tried to replace single quote with double quote and put the full command path
You have two options: ensure /usr/bin is on your PATH (echo $PATH to see if this is the case) or edit the script to call smbclient with the full path (/usr/bin/smbclient)
I need your help in understanding this behaviour of sudo.
sudo -s -- 'ls -l' this command works but sudo 'ls -l' throws error saying
sudo: ls -l: command not found I realize it treats the entire string within quote as single command (including the spaces) but what I don't get is how does it work fine with -s flag but fails when -s is not there.
Without -s, the first argument is the name of the command to execute. With -s, the first argument is a string passed to the -c option of whatever shell ($SHELL or your system shell) is used to execute the argument.
That is, assuming $SHELL is sh, the following are equivalent:
sudo -s -- 'ls -l'
sudo -- sh -c 'ls -l'
From the sudo man page:
-s [command]
The -s (shell) option runs the shell specified by the SHELL environment variable if it is set or the shell as specified in
the password database. If a command is specified, it is passed to the
shell for execution via the shell's -c option. If no command is
specified, an interactive shell is executed.
It behaves like it does because a new shell is spawned which breaks up the words in your "quoted command" like shells do.
When I use the following command, everything works as expected (a new gnome-terminal is open, the current working directory is changed and the terminal remains open):
gnome-terminal -e "bash -c 'cd /';$SHELL"
# ↑
# no space character here
But when I use:
gnome-terminal -e "bash -c 'cd /'; $SHELL"
# ↑
# note the space
I can see a terminal that opens, but I can't see if the current working directory is changed or not because the terminal it closes immediately.
My question is: why this is happening; how can be wrong if I put a space in the second case?
In the first case, gnome-terminal executes
bash -c "cd /;/bin/bash"
in the second case, it runs
bash -c "cd /;" /bin/bash
The first case means "evaluate cd /;/bin/bash", which will cd and run an interactive shell.
The second case means "evaluate cd /; with $0 set to /bin/bash", which will run cd and then exit.
gnome-terminal does its own parsing of the command given to it, using g_shell_parse_argv, which apparently doesn't consider ; to be a word separator, so if a ; is adjacent to a non-whitespace character, it is considered to be part of that non-whitespace character's word.
This can result in surprising behavior if the command you pass to gnome-terminal has shell metacharacters in it.
I used strace on the gnome-terminal process to see what it does. The first command
gnome-terminal -e "bash -c 'cd /';$SHELL"
results in gnome-terminal running the following command
execve("/bin/bash", ["bash", "-c", "cd /;/bin/bash"])
The second command
gnome-terminal -e "bash -c 'cd /'; $SHELL"
results in gnome-terminal running the following command
execve("/bin/bash", ["bash", "-c", "cd /;", "/bin/bash"])
That being said, you should also note that a command such as bash -c 'cd /' will not have a lasting effect on the working directory of any command run after it. So I think that the first command you typed got the desired result only because of the gnome-terminal parsing misfeature, and a more robust way of writing it would be
gnome-terminal -e "bash -c 'cd /;$SHELL'"
I run this command on ubuntu:
su - test -c cp /home/test/toto.txt /home/test/dir
But I have this error!
cp: missing file operand
anyone has an idea about the problem?
thank you
Option -c is understood by command su, taking the next argument (not the remaining) to be the command. That next command is just cp.
Try putting the command into quotes:
su - test -c 'cp /home/test/toto.txt /home/test/dir'
If this is problematic because you want to have quotes inside the command, try using escape instead of the inner quotes:
su - test -c 'echo hello\ \ there'