May I define aliases elsewhere than into .bashrc? - alias

We are several persons using the same login id on Linux Box.
I want to define my own aliases without interfering with anyone.
In the .bashrc, I define a alias to my bash file defining my own aliases.
alias luc=/full/path/to/my/def_alias_luc.sh
The file /full/path/to/my/def_alias_luc.sh contains
#!/bin/bash
echo ""
echo "Defining Luc's aliases"
echo ""
echo ""
echo "aliases before..."
echo ""
alias
alias vimluc="vim -u /full/path/to/my/.vimrc "
echo ""
echo "aliases after"
echo ""
alias
After executing /full/path/to/my/def_alias_luc.sh, the alias is still undefined.
What do I miss ?

Don't you want to source that file (i.e. run it within the existing bash process) rather than spawn off a new bash process (as the first line of the script would suggest you're doing) ?

Related

Running sqlcmd in batch file works but running the same batch file as a scheduled task works and does nothing

I have looked at many SO questions/answers and though some seem similar to my issue they do not seem to be. The answers given fix issues the questions were asking about but will not solve my issue.
I have a batch file...
#ECHO ON
ECHO Disabling the following... >> C:\App\Debug.log
ECHO - V1 >> C:\Apps\Debug.log
FOR /F "tokens=* USEBACKQ" %%F IN (`sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1'"`) DO (
Echo %%F >> C:\Apps\Debug.log
)
EXIT /B
When I run this file at the command prompt it works perfectly fine. When I run it as a scheduled task it show me the echos but nothing for the for loop as expected.
Yes I have made sure the username (using whoami) is the same for the scheduled task set up as the manual run that I do.
Yes I know the user running the script has rights to everything (file access as well as DB access) because it works fine running it from the command prompt.
Scheduled task is set to run wither user is logged on or not.
Any ideas what might be wrong or what I can try for debugging purposes?
Thanks!
sqlcmd is perhaps not enough. cmd.exe in environment of scheduled task may fail to find the executable using local PATHEXT and local PATH environment variables. The executable should be specified with full qualified file name, i.e. drive + path + name + extension. Then the batch file does not anymore depend on the environment variables PATH and PATHEXT because of all files are referenced with full qualified file name.
for executes the specified command line with starting in background one more command process with %ComSpec% /c and the specified command line appended. This means executed is following with Windows installed on drive C::
C:\Windows\System32\cmd.exe /c sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1'"
for captures everything written to handle STDOUT of started command process. The lines of captured output are processed line by line by for after started cmd.exe terminated itself. Error messages output by started cmd.exe or the commands/executables executed by Windows command processor in background to handle STDERR are redirected to handle STDERR of command process processing the batch file and printed to console. But there is no console window on running a batch file as scheduled task. So error messages cannot be seen in this case.
The for command line can be modified easily here to get also error messages written into the C:\Apps\Debug.log.
FOR /F "tokens=* USEBACKQ" %%F IN (`sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1' 2^>^&1"`) DO (
The Microsoft article Using command redirection operators explains 2>&1. The two operators > and & must be escaped with ^ to be interpreted as literal characters on Windows command processor parsing the for command line before executing finally for which executes next %ComSpec% /c with the specified command line on which 2^>^&1 is changed already to 2>&1.
Does the log file C:\App\Debug.log contain with this modification following two lines?
'sqlcmd' is not recognized as an internal or external command,
operable program or batch file.
Yes, then no executable with file name sqlcmd is found by started cmd.exe. The best solution is referencing this executable with full qualified file name. See also: What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?
Otherwise sqlcmd outputs perhaps an error message which should be now also in the log file C:\App\Debug.log.
It would be also possible to use following command line to let background cmd.exe write the error messages into a separate error log file C:\App\Error.log:
FOR /F "tokens=* USEBACKQ" %%F IN (`sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1'" 2^>C:\App\Error.log`) DO (
"tokens=* usebackq" results in first deleting all leading horizontal tabs and normal spaces on non-empty lines by for, then checking if the remaining line starts with ; in which case the line is also ignored and finally assigning the captured line not starting with ; and with leading tabs/spaces removed to loop variable F for further processing.
Better would be using the options usebackq^ delims^=^ eol^= not enclosed in double quotes which requires escaping the two spaces and the two equal signs with caret character ^ to be interpreted as literal characters by cmd.exe on parsing the command line before executing for. The line splitting behavior is disabled completed with delims= because of the definition of an empty list of delimiters. And no line except an empty line is ignored anymore because of end of line character modified from default ; to no character.
Finally a space on an echo line left to redirection operator >> is also output by echo and for that reason written as trailing space into the log file. Therefore no space should be used left to > or >> on printing a line with echo redirected into a file. But care must be taken on omitting the space character left to the redirection operator. The word left to redirection operator should not be 1, 2, ..., 9 as this would result in redirecting the output to these numbered handles into the specified file instead of the character 1, 2, etc. So if unknown text should be written into a file, it is better to specify first the redirection operator > or >> and the full qualified file name and next the echo command with the text to output. See also: Why does ECHO command print some extra trailing space into the file?
The three command lines with echo would be for this batch file:
ECHO Disabling the following...>> C:\App\Debug.log
ECHO - V1>> C:\Apps\Debug.log
>>C:\Apps\Debug.log ECHO %%F
following... is safe for being correct written into the file as also V1. %%F could be just 1 or a string ending with a space and a single digit and so it is better to specify the redirection first on the last echo command line to get finally executed by cmd.exe the command line ECHO %%F 1>>C:\Apps\Debug.log.

Why doesn't sh with errexit work with a command list?

If I run the following shell script as a normal user, it aborts at line three as expected:
set -o errexit
echo foo > /bar
echo $?
Here is the output:
$ sh test1.sh
test.sh: 3: test.sh: cannot create /bar: Permission denied
However, if the echo command is a part of a compound list, the execution continues after the failing command and prints the exit code:
set -o errexit
{ echo foo; } > /bar
echo $?
Here is the output:
$ sh test2.sh
test.sh: 3: test.sh: cannot create /bar: Permission denied
2
How come the script doesn't abort? On the other hand, if I change the curly braces to parentheses it works like how I would expect.
The POSIX specification states that a shell "may exit" if a redirection error occurs with a compound command.
bash chooses to exit if the compound command is a subshell command ((...)), but otherwise chooses not to. I am not aware of the rationale for this distinction; it may be historical in nature.
set -e has many quirks, and often will not behave the way you expect. Many people advise that you simply not use it.

SQLCMD error in Batch file. Invalid Filename

echo off
if "%4" == "" goto usage
cd %3
mkdir Logs
echo Logs can be found in %3\Logs
echo
goto %4
:smmdsp
echo Updating %2..xyz table on %1
sqlcmd -S %1 -E -p -e -d %2 -i "%3\xyz.SQL" > %3\Logs\xyz.SQL.log
goto done
:usage
echo.
echo Usage
echo.
echo where SqlServer = SQL Server name
echo Database = configuration database
echo InstallPath = path to the software update files
echo Feature = Feature to update
echo.
:done
This script works if i have the batch file in C drive C:\XYZ , but if there are spaces in the path or if its in program files 86 folder C:\Program Files (x86) .It Gives out a error that says
How to handle this scenario... ?? Thank you
OK, This is the answer.
In my multiple decades of experience as a professional programmer, I have learned that most bugs that are not easily solved are not difficult because the problem itself is difficult, but because of human nature we make assumptions about the elements of our code that are simply incorrect, but we cannot "see" it because of that innate assumption. To compound that error in our own behavior, once we discover the error in our thought process we tend to be too embarrassed to tell others what the source of the issue was.
At this point in my career... I have nothing left to prove, and am more concerned with saving others the pain and waste of valuable coding time.
This is one of those insidious things that is due mostly to Microsoft being presumptuous, and removing file extensions from view by default. ...grrr I left my xanax at home today.
What I have done here, by my assuming that the file name I was trying to use as a parameter to the sqlcmd call was ... -i c:\temp\myscript.sql
and I was completely wrong. The file I was trying to reference was
c:\temp\myscript.sql.txt
but Microsoft in their attempt to try to help me removed the actual extension from view in file explorer and fooled me into thinking I had the correct file name. I didn't. Once I realized that I corrected the file name, which then made my code reference correct, and everything worked perfectly.
Try with strings :
sqlcmd -S "%1" -E -p -e -d %2 -i "%3\xyz.SQL" > %3\Logs\xyz.SQL.log

script to run a certain program with input from a given directory

So I need to run a bunch of (maven) tests with testfiles being supplied as an argument to a maven task.
Something like this:
mvn clean test -Dtest=<filename>
And the test files are usually organized into different directories. So I'm trying to write a script which would execute the above 'command' and automatically feed the name of all files in a given dir to the -Dtest.
So I started out with a shellscript called 'run_test':
#!/bin/sh
if test $# -lt 2; then
echo "$0: insufficient arguments on the command line." >&1
echo "usage: $0 run_test dirctory" >&1
exit 1
fi
for file in allFiles <<<<<<< what should I put here? Can I somehow iterate thru the list of all files' name in the given directory put the file name here?
do mvn clean test -Dtest= $file
exit $?
The part where I got stuck is how to get a list of filenames.
Thanks,
Assuming $1 contains the directory name (validation of the user input is a separate issue), then
for file in $1/*
do
[[ -f $file ]] && mvn clean test -Dtest=$file
done
will run the comand on all files. If you want to recurse into subdirectories then you need to use the find command
for file in $(find $1 -type f)
do
etc...
done
#! /bin/sh
# Set IFS to newline to minimise problems with whitespace in file/directory
# names. If we also need to deal with newlines, we will need to use
# find -print0 | xargs -0 instead of a for loop.
IFS="
"
if ! [[ -d "${1}" ]]; then
echo "Please supply a directory name" > &2
exit 1
else
# We use find rather than glob expansion in case there are nested directories.
# We sort the filenames so that we execute the tests in a predictable order.
for pathname in $(find "${1}" -type f | LC_ALL=C sort) do
mvn clean test -Dtest="${pathname}" || break
done
fi
# exit $? would be superfluous (it is the default)

Why doesn't prompt for input in a batch file allow for a DASH character?

I have this simple little batch file program that I wrote but it fails if I enter a database name that contains a "-" character. Im not exactly sure why but I wish I could figure out a way around this?
:: open DB batch file
#echo off
:: starts Sql Server Management Studio Express 2005
:: and opens it to a specific database with query
:: window already open
cls
:SHOWDBNAMES
echo Database names detected on this system:
echo.
"%PROGRAMFILES%\Microsoft SQL Server\90\Tools\Binn\OSQL.EXE" -h-1 -S . -E -Q "SELECT CAST(name AS VARCHAR(30)) FROM sysdatabases"
#echo.
set DBNAME=
set /P DBNAME=What database name would you like to open (choose from list)?
if "%DBNAME%" == "" (
echo.
echo I don't recognize your selection. Try again.
goto SELECTDB
)
:SHOWTABLES
cls
echo.
echo Tables that you can query from %DBNAME% are:
echo.
"%PROGRAMFILES%\Microsoft SQL Server\90\Tools\Binn\OSQL.EXE" -h-1 -S . -E -Q "use [%DBNAME%];SELECT CAST(name AS VARCHAR(30)) FROM sys.Tables ORDER BY name"
echo.
:RUNIT
sqlwb.exe -nosplash -S . -E -d %DBNAME%
pause
:EOF
Try enclosing the database name in square brackets:
[database-name]
EDIT
The following should work - you need to quote the database name in the call to sqlwb.exe:
:SHOWTABLES
cls
echo.
echo Tables that you can query from %DBNAME% are:
echo.
"%PROGRAMFILES%\Microsoft SQL Server\90\Tools\Binn\OSQL.EXE" -h-1 -S . -E -Q "SELECT CAST(name AS VARCHAR(30)) FROM [%DBNAME%].sys.Tables ORDER BY name"
echo.
:RUNIT
sqlwb.exe -nosplash -S . -E -d "%DBNAME%"
I've got to ask though - what's the point of this script? The built-in SSMS object explorer gives you all this information for free.
Also, your script doesn't take account of SQL server instances other than the default - SQL Server Express is installed as <machine_name>\SQLEXPRESS by default.
Why don't you just try an underscore (_)?
Is it failing on the sqlwb.exe line when the dash is the first letter in the database name? If so, your problem is that sqlwb is misinterpreting the database name as a command line option. There should be some way to make it not do that; check the manual.