Bash Script cd not working even it exists - bash

I am running a bash script in unix. The directory exists but it wont work when i change directory in the script.
The script is located at: /oracle/archive.sh
I run the script with: sh archive.sh
Script:
SALES_DIR="/oracle/sales/"
cd $SALES_DIR
pwd
The output show:
: No such file or directory: /oracle/sales/
/oracle
It clearly show that it is not able to change the directory, but the pwd command is working.

Your problem was that you were using editor which saved your script with CR character (more about that https://en.wikipedia.org/wiki/Newline. With tr, you've converted the script to use only Unix end-of-lines characters (LF), saying that you removed the \r character from the script.
tr -d "\r" < archive.sh > archive.new.sh
You can also detect special characters when running
cat -ve archive.sh
So in your case instead of changing directory to /oracle/sales/ you were actually trying to cd to /oracle/sales/\r

Related

Running a cd command after user input in bash script will not change directory [duplicate]

This question already has answers here:
Why can't I change directories using "cd" in a script?
(33 answers)
Closed 6 years ago.
I am trying to create a script whereby I have list of numerical test folders and want users to be able to cd into one of them after inputting the folder number.
The script correctly concatenates the input but on running the script it does not actually execute the cd command to the required directory?
It echo's to the screen but then just sits there as if awaiting a further prompt?
Can anyone advise what I am missing please? Script 'chgdir' is as below:
#!/bin/bash
#
# Script to move to test##dir (using input from user for dir number)
echo "Enter test directory number as ## and hit Return"
read dirnum
echo "cd /home/John/test$dirnum""dir"
However on running the script outputs the command to the screen but does not 'cd' and just remains in ~/bin?
cd /home/John/test01dir
John#John-PC ~/bin
P.S I am completely new to bash scripting as you can tell so any help really appreciated.
All your script does is to echo the command that you formed. You need to actually execute the cd command as well as just echoing it.
cd /home/John/test ${dirnum}dir
The {} around the variable name allows the shell to distinguish the variable name from the extra characters appended after it.
That will change the directory inside the script. To have it apply afterwards, you will need to source the script (with dot "." or "source") to affect the shell you are running in.
Your script just prints the command. That's all the echo command does. It doesn't execute it, because you didn't tell it to.
You could execute the cd command by replacing the echo command with this:
cd "/home/John/test${dirnum}dir"
But if that's the last line of your script, it won't do anything useful. Doing a cd inside a script doesn't affect anything but the script itself.
If you want to cd from a script and have it take effect in the invoking shell, you can source the script rather than executing it:
. ./thescript
or you can have the script print the command you want to execute and eval its output:
eval "`./thescript`"
(To be clear, if you source the script using the . command, it needs to execute the cd command; if you val its output, the script needs to print the command.)

How do I call rename successfully from a bash script on Ubuntu?

I have a bash script #!/usr/bin/env bash that is called part of a make process. This script creates a directory with the files pertinent to a realise and then tars them up. I would like to take a copy of the directory and rename some of the files to replace the version identifier with the word "latest". This will make it simple to script the acquisition of the latest file from a web-server. When I run my script, the call to rename seems to do nothing, why is that?
#!/usr/bin/env bash
DATE_NOW="$(date +'%Y%m%d')"
product_id_base="$1"
firmware_dir="${product_id_base}-full-${DATE_NOW}"
# ...rest of file ommitted to protest the innocent
# It creates and fills the ${firmware_dir} with some files that end in
# -$DATE_NOW.<extention> and I would like to rename the copies of them so that they end in
# -latest.<extention>
cp -a "./${firmware_dir}" "./${product_id_base}-full-latest"
# see what there is in pwd
cd "./${product_id_base}-full-latest"
list_output=`ls`
echo $list_output
# Things go OK until this point.
replacment="'s/${DATE_NOW}/latest/'"
rename_path=$(which rename)
echo $replacment
perl $rename_path -v $replacment *
echo $cmd
pwd
$cmd
echo "'s/-${DATE_NOW}/-latest/g'" "${product_id_base}-*"
echo $a
# check what has happened
list_output=`ls`
echo $list_output
I call the above with ./rename.sh product-id and get the expected output from ls that indicates the present working directory is the one full of files that I want renamed.
$ ./rename.sh product-id ET-PIC-v1.1.dat ET-PIC-v1.1.hex
product-id-20160321.bin product-id-20160321.dat
product-id-20160321.elf product-id-20160321.gz 's/20160321/latest/'
/home/thomasthorne/work/product-id/build/product-id-full-latest
's/-20160321/-latest/g' product-id-*
ET-PIC-v1.1.dat ET-PIC-v1.1.hex product-id-20160321.bin
product-id-20160321.dat product-id-20160321.elf product-id-20160321.gz
What I hopped to see was some renamed files. When I directly call the rename function from a terminal emulator I see the rename occur.
~/work/product-id/build/product-id-full-latest$ rename -vn
's/-20160321/-latest/g' * product-id-20160321.bin renamed as
product-id-latest.bin product-id-20160321.dat renamed as
product-id-latest.dat product-id-20160321.elf renamed as
product-id-latest.elf ...
I have tried a few variations on escaping the strings, using ` or $(), removing all the substitutions from the command line. So far nothing has worked so I must be missing something fundamental.
I have read that #!/usr/bin/env bash behaves much like #!/bin/bash so I don't think that is at play. I know that Ubuntu and Debian have different versions of the rename script to some other distributions and I am running on Ubuntu. That lead me to try calling perl /usr/bin/rename ... instead of just rename but that seems to have made no perceivable difference.
This string:
replacment="'s/${DATE_NOW}/latest/'"
will be kept exactly the same because you put it between single quotes.
Have you tried with:
replacment="s/${DATE_NOW}/latest/"
This one worked on my Ubuntu, without perl:
$ ./test_script
filename_20160321 renamed as filename_latest
filename2_20160321 renamed as filename2_latest
filename3_20160321 renamed as filename3_latest
test_script content being:
#!/bin/bash
DATE_NOW="$(date +'%Y%m%d')"
replacment="s/${DATE_NOW}/latest/"
rename -v $replacment *

Unable to access PDS in z/OS unix shell

I'm trying to copy a text file from within the z/OS unix shell to a PDS titled P2.OUTPUT($010), but whenever i run the command cp file.txt "//P2.OUTPUT($010)" i get an error stating that P2.OUTPUT(-sh10) is an invalid location. For whatever reason, whenever I run the command $010 becomes -sh10. I've tried putting $010 in '' and a few other things but no matter what I do it doesn't seem to work. I believe it's an issue with accessing the file and not with the cp command because I can't view the contents of the member using the cat command either, and any error trying to access the member using any command lists it as -sh10 instead of $010. Any idea what I'm doing wrong?
The problem is that the unix shell interprets $0 as an environment-variable that has the value -sh as can be seen when using echo $0, so your command becomes cp file.txt "//P2.OUTPUT(-sh10)".
Try escaping the $ using a backslash: cp file.txt "//P2.OUTPUT(\$010)".

Windows TYPE to Console recreated using Unix Shell scripting

We have simple Windows batch files that when an error occurs, an "ONCALL.bat" file is run to display support information that is maintained in a separate oncall.txt text file. This is our SOP.
ONCALL.BAT:
set scriptpath=%~dp0
TYPE "%scriptpath%oncall.txt"
I have zero experience with Unix and Shell scripts and I need to quickly provide a shell script equivalent to run in a Unix environment.
Could someone please provide me the .sh equivalent of this code?
Assuming that the help file and the script are in the same directory:
#!/bin/sh
SCRIPTPATH=`dirname "$0"`
cat "$SCRIPTPATH"/oncall.txt
$0 is the file path of the current script; the dirname command extracts the directory part of it. This way you can avoid using a hard-coded path for the help file within the script.
cat oncall.sh
#!/bin/bash
scriptpath=/path/to/scripts
cat ${scriptpath}/oncall.txt
After you create your file, it can't hurt to run
dos2unix oncall.sh
Just to be sure there are no windows Ctrl-M chars that will totally mystify you with the way they can screw up Unix script processing.
THEN
chmod 755 oncall.sh
To make the script executable.
confirm with
ls -l oncall.sh
You should see listing like
-rwxr-xr-x 1 userName grpname 5263 Nov 21 14:44 oncall.sh
Finally, call the script with a full or relative path, i.e.
./oncall.sh
OR
$PWD/oncall.sh
The first line is called the "shebang" line, and when your script is called, the OS reads the first line of the file, to find out what program to run to interpret the rest of the script file.
You may want/need to use as the first line "shebang" one of the following, but bash is a good guess
#!/bin/ksh
#!/bin/sh
#!/bin/ash
#!/bin/dash
#!/bin/zsh
OR you may worst case, your shell lives in a non-standard directory, then you'll have to spell that out, i.e.
#!/usr/bin/ksh
All shell support debugging arguments for trace and variable expansion like
#!/bin/ksh -vx
Or you can wrap just certain lines to turn debugginng on and off like
set -vx
cat ${scriptpath}/oncall.txt
set +vx
Given that
The ~dp special syntax between the % and the 0 basically says to expand the variable %0 to show the drive letter and path, which gives you the current directory containing the batch file!
I think /path/to/scripts is a reasonable substitute, scriptpath=$PWD would be a direct replacement, as there are no drive letters in Unix. The problem there, is that you either rely on unix PATH var to find your script or you cd /path/to/scripts and then run ./oncall.sh using the relative path./ to find the file without naving added a value to PATH.
IHTH.

command substitution but without breaking output into multiple arguments

Is there a way to do command substitution in BASH shell without breaking output into multiple arguments?
I copy the path of some directory (from the location bar in a GUI file browser) to clipboard and then issue the following command, where the command xsel returns the clipboard content, which is the path of the directory in this case:
cd `xsel`
But some path contain spaces or may even contain some special characters used by BASH.
How can I pass the output of a command as a single argument and without BASH messing with special characters?
cd "$(xsel)"
seems to handle all special characters (including $ and spaces).
My test string was boo*;cd.*($\: $_
$ mkdir "$(xsel)"
$ ls
boo*;cd.*($\: $_
$ file boo\*\;cd.\*\(\$\\\:\ \$_/
boo*;cd.*($\: $_/: directory
$ cd "$(xsel)"
$ pwd
/tmp/boo*;cd.*($\: $_
Have you tried:
cd "`xsel`"
That should do the job, unless you have dollars($) or back-slashes (\) in your path.
If you aren't doing this programmatically, most terminals in Linux let you paste from the clipboard with a middle-click on your mouse. Of course, you'll still need to put quotes before and after your paste, like #dave suggests.

Resources