Stuck with While loop in WSL2 - wsl-2

I am in the very basic of the basic with Shell. In general, I only use the WSL2 for ssh. Now, I write a loop, so I google for an example to see how it works. Here is my ref:https://ryanstutorials.net/bash-scripting-tutorial/bash-loops.php. The problem is that even if I just copy and paste their examples, I get the error:
loop_learning.sh: line 4: $'\r': command not found
loop_learning.sh: line 10: syntax error near unexpected token `done'
loop_learning.sh: line 10: `done'
This is the code that I just copy and paste:
#!/bin/bash
# Basic while loop
counter=1
while [ $counter -le 10 ]
do
echo $counter
((counter++))
done
echo All done

The problem is probably that you copy-pasted the script from Windows and tried to execute it from Linux. Windows uses CR in addition to NL for new lines, where Linux uses only '\n' and finds the former ('\r') strange.
Try something like this from your WSL2 terminal:
sed 's/\r//g' your-copied-script.sh > your-clean-script.sh
And execute your-clean-script.sh

Related

Why can't I use $(...) in PS1 instead of backticks?

My current PS1:
PS1='\[\033]0;$TITLEPREFIX:${PWD//[^[:ascii:]]/?}\007\]\n\[\033[32m\]\u#\h \[\033[35m\]`date +%Y-%m-%d,%H:%M:%S` \[\033[33m\]\w\[\033[36m\]`__git_ps1`\[\033[0m\]\n$: '
Yes, it's a mess, but it serves me well - my prompts look like this:
P2759474#RVPTINTCL415MQC 2017-10-06,11:20:18 ~/repos/jdk (master)
They are even color coded, with user#machine in green, timestamp in purple, current location in yellow, and any git branch in blue. I'm just a little annoyed that I have to use backticks instead of a $() construct.
Anyone know why? Willing to help me understand it? It's only a problem when parsing complex prompt values with subshell commands, and only a problem then because I want to understand why it matters there... General improvement suggestions always welcome while we're at it.
Update -
Currently when I try to use $() I get a lot of
bash: command substitution: line 1: syntax error near unexpected token ')'
bash: command substitution: line 1: 'date +%Y-%m-%d,%H:%M:%S)'
bash: command substitution: line 1: syntax error near unexpected token ')'
bash: command substitution: line 1: '__git_ps1)'
My env has
BASH_VERSINFO=([0]="4" [1]="3" [2]="42" [3]="5" [4]="release" [5]="x86_64-pc-msys")
BASH_VERSION='4.3.42(5)-release'
[ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no;
That tells me something, maybe... Thanks!
When you start trying to embed commands in your prompt, it is time to start using PROMPT_COMMAND.
# You won't even have to put the title-bar stuff in your prompt
# and there are already shortcuts for date and time
set_titlebar () {
printf '\033]0;%s:%s\007' "$TITLEPREFIX" "${PWD//[^[:ascii:]]/?}"
}
set_prompt () {
PS1='\[\033[32m\]\u#\h ' # user#host in green
PS1+='\[\033[35m\]\D{%Y-%m-%d},\t ' # Don't need date
PS1+='\[\033[33m\]\w\[\033[36m\]' # Directory in orange
PS1+=$(__git_ps1) # git info, if appropriate
PS1+='\[\033[0m\]\n$: '
}
PROMPT_COMMAND='set_titlebar;set_prompt'

I can't get my bash script to run

This is the script that I used to that will not run, but I am hoping someone can help me figure out what the issue is. I am new to unix
#!/bin/bash
# cat copyit
# copies files
numofargs=$#
listoffiles=
listofcopy=
# Capture all of the arguments passed to the command, store all of the arguments, except
# for the last (the destination)
while [ "$#" -gt 1 ]
do
listoffiles="$listoffiles $1"
shift
done
destination="$1"
# If there are less than two arguments that are entered, or if there are more than two
# arguments, and the last argument is not a valid directory, then display an
# error message
if [ "$numofargs" -lt 2 -o "$numofargs" -gt 2 -a ! -d "$destination" ]
then
echo "Usage: copyit sourcefile destinationfile"
echo" copyit sourcefile(s) directory"
exit 1
fi
# look at each sourcefile
for fromfile in $listoffiles
do
# see if destination file is a directory
if [ -d "$destination" ]
then
destfile="$destination/`basename $fromfile`"
else
destfile="$destination"
fi
# Add the file to the copy list if the file does not already exist, or it
# the user
# says that the file can be overwritten
if [ -f "$destfile" ]
then
echo "$destfile already exist; overwrite it? (yes/no)? \c"
read ans
if [ "$ans" = yes ]
then
listofcopy="$listofcopy $fromfile"
fi
else
listofcopy="$listofcopy $fromfile"
fi
done
# If there is something to copy - copy it
if [ -n "$listofcopy" ]
then
mv $listofcopy $destination
fi
This is what I got and it seems that the script didn't execute all though I did invoke it. I am hoping that someone can help me
[taniamack#localhost ~]$ chmod 555 tryto.txt
[taniamack#localhost ~]$ tryto.txt
bash: tryto.txt: command not found...
[taniamack#localhost ~]$ ./tryto.txt
./tryto.txt: line 7: $'\r': command not found
./tryto.txt: line 11: $'\r': command not found
./tryto.txt: line 16: $'\r': command not found
./tryto.txt: line 43: syntax error near unexpected token `$'do\r''
'/tryto.txt: line 43: `do
Looks like your file contains Windows new line formatting: "\r\n". On Unix, a new line is just "\n". You can use dos2unix (apt-get install dos2unix), to convert your files.
Also have a look at the chmod manual (man chmod).
Most of the time i just use chmod +x ./my_file to give execution rights
I see a few issues. First of all, a mode of 555 means that no one can write to the file. You probably want chmod 755. Second of all, you need to add the current directory to your $PATH variable. In Windows, you also have a %PATH%, but by default the current directory . is always in %PATH%, but in Unix, adding the current directory is highly discouraged because of security concerns. The standard is to put your scripts under the $HOME/bin directory and make that directory the last entry in your $PATH.
First of all: Indent correctly. When you enter a loop or an if statement, indent the lines by four characters (that's the standard). It makes it much easier to read your program.
Another issue is your line endings. It looks like some of the lines have a Windows line ending on them while most others have a Unix/Linux/Mac line ending. Windows ends each line with two characters - Carriage Return and Linefeed while Unix/Linux/Mac end each line with just a Linefeed. The \r is used to represent the Carriage Return character. Use a program editor like vim or gedit. A good program editor will make sure that your line endings are consistent and correct.

Lubuntu: Using .sh script as a keybind, code works, executing script gives errors

This is my first ever post on stackoverflow, hope I don't break any rules. I'm a complete Linux newbie (installed Lubuntu 14.04 64bit last night) so be duly warned.
In short, I'm trying to get my laptop touchpad toggle to work (Fn+F3 on my Inspiron5110). I have a bash script:
#!/bin/bash
if [ $(synclient -l | grep TouchpadOff | awk '{print $3}') == 1 ] ; then
synclient touchpadoff=0;
else
synclient touchpadoff=1;
fi
I got it from http://crunchbang.org/forums/viewtopic.php?id=10996 . If I paste the script code in the terminal and execute it, it works (touchpad goes on/off). However, I want to bind it to a key so in my lubuntu-rc.xml I've added the following:
<!-- disable touchpad -->
<keybind key="XF86TouchpadToggle">
<action name="Execute">
<command>/usr/local/bin/touchpad.sh</command>
</action>
</keybind>
When I press the necessary key combo however I get "Failure to execute child process "/usr/local/bin/touchpad.sh" (No such file or directory)". However I can see in this directory, both in the file manager and when I use ls in the terminal that the file is there:
/usr/local/bin$ ls -l
total 4
-rwxrwxr-x 1 paspaldzhiev paspaldzhiev 145 юни 2 22:54 touchpad.sh
I used chmod +x touchpad.sh to make it executable.
Now, where this gets even more confusing:
If I use bash /usr/local/bin/touchpad.sh I get:
paspaldzhiev#areuexperienced:/usr/local/bin$ bash touchpad.sh
touchpad.sh: line 6: syntax error near unexpected token `fi'
touchpad.sh: line 6: `fi'
Though as I've said above I know for a fact that the code works if I just paste it in the terminal.
Further, if I use ./touchpad.sh I get :
paspaldzhiev#areuexperienced:/usr/local/bin$ ./touchpad.sh
bash: ./touchpad.sh: /bin/bash^M: bad interpreter: No such file or directory
Just to note that I'm not very sure what the difference between bash touchpad.sh and ./touchpad.sh is in terms of execution, it's just that my more Linux-savvy friends told me to try these :D.
In any case, I have no idea how to proceed henceforth, could anyone please shed a light on what I'm doing wrong?
Thank you very much!
The ^M in your last error msg is your big hint ; -). Somehow you have used a windows editor, file transfer or something. Try dos2unix touchpad.sh. It will remove all the CR (^M) chars from end of lines. It should work then. Good luck. – shellter
There is no need for script, since there is no need for if instruction.
Place this piece of code in your lubuntu-rc.xml
<keybind key="XF86TouchpadToggle">
<action name="Execute">
<command>synclient TouchpadOff=$((1-$(synclient | grep TouchpadOff | awk '{print $3}')))</command>
</action>
</keybind>

How do I fix unexpected end of file in bash script?

I had much luck last time I submitted a question so here goes: I am trying to debug a somewhat large BASH script when I get the following error:
./test.sh: line 418: unexpected EOF while looking for matching `"'
./test.sh: line 427: syntax error: unexpected end of file
The code below starts at line 400:
echo "###########################################################"
echo
;;
4)
culebra_carriers
get_month
get_day
logs_cdrs
logs_wap
get_mdn
echo
echo "###########################################################"
echo
echo "Searching for activity of $mobileNumber on $MON $DAY......."
echo
zgrep $mobileNumber $HOME/culebrapeak/$LOGCDR/$CULEB/$MON/$WAPLOG
echo
echo "###########################################################"
echo
;;
esac
done
}
clear
main_menu
How do I make this error go away? It looks like I have the double quotes in all the right places... but this is only my 4th or 5th bash script... so please go easy on me.
I was, indeed, missing a double quote at the top of my script. Thanks to all for the help!
A good way to solve problems like this is to use a text editor that highlights code between quotes. Short of that, if the "find" feature of your text editor gives a count too, you may be able to use it to quantitatively detect start/end character symmetry problems. The highlighting from the find feature will aide your eye tremedously.

backspace issue on linux file

I use EditPlus to write linux bash programs. after writting when i move files to server i get these kind of errors:
sleep: invalid time interval `2\r'
Try `sleep --help' for more information.
/usr/bin/program: line 9: $'\r': command not found
/usr/bin/program: line 10: $'}\r': command not found
/usr/bin/program: line 11: $'\r': command not found
/usr/bin/program: line 12: syntax error near unexpected token `$'{\r''
'usr/bin/program: line 12: `stop() {
I have also used dos2unix to fix this issue but no success. I want to know that is there any way that I can avoid this kind of problems. it waste alot of time. is there any better editor or some way to fix this issue?
EDIT:
What I do to solve this issue is that I vi a file in linux and then copy line by line from windows file to linux file and then it works. these are lines of my code:
line7:udevadm control --reload-rules
sleep 2
echo
echo $(date +"%b %e %T") hostname Program[$$]: Program Started | tee -a /var/log/messages
echo
}
stop() {
You need to change file preferences: go to Preferences -> Files and change "Create new file as " to UNIX. Also, your might want to enable "Check invalid CR/LF, null character when loading" option.
For already produced files
cat OLDFILE | tr -d '\r' > NEWFILE
should help. You can't just redirect the output to the input:
cat FILE | tr -d '\r' > FILE
since this will truncate the input file before it is read.
In contrast to similar programs, this is not eligible for the useless-use-of-cat award, since tr doesn't accept a filename as parameter.
Setting the "line ending sequence" in VSCode / atom from CRLF TO LF and saving worked for me

Resources