Will ailas be dropped in xterm after Linux login? - linux

I'm using tcsh in red hat with a XFCE client. I want to make some setting in my .cshrc be execute only one time. I'm using the following command but it seems strange to me. The LOAD_SETTING env was reported as set when I start a xterm but the alias in the setting cannot be found. It seems my .cshrc was sourced at login time (I got the LOAD_SETTING environment variable set ) but some setting (at least alias) are not inherited. My question is which setting will be loaded and which will be lost in the terminal when I just start the terminal just after login?
I tried to change 'setenv LOAD_SETTING 3' to 'set LOAD_SETTING=3' and it seems works as expected: setting will be loaded when I start the terminal at first time but I just worried about the NOT environment variable is not safe enough as I'm trying to avoid SGE source my .cshrc for multi times.
if ! $?LOAD_SETTING then
echo "loading "`pwd`"/project_setting.csh"
source /project/project_setup
#force useful path order
set path = (/tools/bin/x86_64/ /tools/cad/bin /sf/tools/cad/scripts /oge/sfgrid/6.2u5p1/wrapper /oge/sfgrid/6.2u5p1/bin/lx26-amd64 . /bin /sbin /usr/bin /usr/sbin /sf/tools/bin /sf/tools/cad/wrapper/bin $path)
#delete repeated path
set path=(`echo $path | perl -e 'print join(" ", grep { not $seen{$_}++ } split(/ /, scalar <>))'`)
alias greg 'set ret=`find_tot` && $ret/bin/greg'
setenv LOAD_SETTING 3
exit 1
else
echo "project_setting.csh has already been loaded, abort to load it again!"
exit 1
endif

Related

What's the equivalent to ${var:-defaultvalue} in fish?

Hello I am trying to translate my .bashrc to fish format almost done, mostly is clear on the documentation but this part is giving me a headache.. is so my gnupg works with my yubikey ssh etc etc..
The fish version is latest 3.0 under Arch GNU/Linux
original on BASH:
# Set SSH to use gpg-agent
unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
export SSH_AUTH_SOCK="/run/user/$UID/gnupg/S.gpg-agent.ssh"
fi
echo "UPDATESTARTUPTTY" | gpg-connect-agent > /dev/null 2&>1
Mine half converted into fish:
set -e SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]
set -x SSH_AUTH_SOCK="/run/user/$UID/gnupg/S.gpg-agent.ssh"
end
echo "UPDATESTARTUPTTY" | gpg-connect-agent > /dev/null 2>&1
so as you see above I have so far converted the stdin and stderror pine and the unset variable with set -e the error I am having is a bit more obscure to me:
~/.config/fish/config.fish (line 33): ${ is not a valid variable in fish.
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]
^
from sourcing file ~/.config/fish/config.fish
called during startup
Any help will be much appreciated,
BTW will be nice a migrate too :) are there any out there?
[edit] ok got this working thanks to the response below, now all my bash environment, profile, bashrc etc is translated to fish and using it solely as my shell 100%
You should not change your login shell until you have a much better understanding of fish syntax and behavior. For example, in fish the equivalent of $$ is %self or $fish_pid depending on which fish version you are using. You should always specify the version of the program you are having problems with.
Assuming you're using fish 2.x that would be written as
if not set -q gnupg_SSH_AUTH_SOCK_by
or test $gnupg_SSH_AUTH_SOCK_by -ne %self
set -gx SSH_AUTH_SOCK "/run/user/$UID/gnupg/S.gpg-agent.ssh"
end
Also, notice that there is no equal-sign between the var name and value in the set -x.
Since ${var:-value} expands to value if $var is empty, you can always replace it by writing your code out the long way:
begin
if test -n "$gnupg_SSH_AUTH_SOCK_by"
set result "$gnupg_SSH_AUTH_SOCK_by"
else
set result 0
end
if [ "$result" -ne %self ]
set -x SSH_AUTH_SOCK "/run/user/$UID/gnupg/S.gpg-agent.ssh"
end
set -e result
end
Note that I don't use (a) endorse, (b) condone the use of, or (c) fail to hold unwarranted prejudices against users of, fish. Thus, my advice is very much suspect, and it's likely that there are considerably better ways to do this.
I had a similar question, related to XDG_* variables.
var1="${XDG_CACHE_HOME:-$HOME/.cache}"/foo
var2="${XDG_CONFIG_HOME:-$HOME/.config}"/foo
var3="${XDG_DATA_HOME:-$HOME/.local/share}"/foo
some-command "$var1" "$var2" ...
What I found as the best alternative is to simply set univeral variables once for the defaults--
set -U XDG_CACHE_HOME ~/.cache
set -U XDG_CONFIG_HOME ~/.config
set -U XDG_DATA_HOME ~/.local/share
Then in fish config file(s) or scripts, simply use "$XDG_CONFIG_HOME"/.... The value of an exported environment variable will override the universal variable if set, otherwise the universal variable is there as a default/fallback. If the universal variable is used, it is not exported to child processes, while an exported environment variable is, which provides the full equivalent to bash|zsh parameter expansion.

How Can I prevent duplicate change text file in linux?

I have successfully changed text in linux using this shell script
vi -e .bash_profile << END
i
PATH=\$PATH:\$HOME/bin:/usr/pgsql-9.4/bin
export PATH
PGDATA=/usr/pgsql-9.4/data
export PGDATA
.
w
q
END
but I have a problem.
If I execute script twice then duplicate in text file.
So, I want to prevent this situation. How Can I fix it?
Well that depends... if the string "PATH=$PATH:$HOME/bin:/usr/pgsql-9.4/bin" can appear at other places in side the file then we could not use it as an indicator that your vi has already done its work. But if the string otherwise does not appear we could wrap the whole thing
grep -q 'PATH=[$]PATH:[$]HOME/bin:/usr/pgsql-9.4/bin' .bash_profile
if [ $? -eq 1 ]
then
# do your vi stuff here
fi
You might replace the if stuff by
test $? -eq 0 && exit 0
if you were not going to do anything after the vi stuff

What does `set -x` do?

I have a shell script with the following line in it:
[ "$DEBUG" == 'true' ] && set -x
set -x enables a mode of the shell where all executed commands are printed to the terminal. In your case it's clearly used for debugging, which is a typical use case for set -x: printing every command as it is executed may help you to visualize the control flow of the script if it is not functioning as expected.
set +x disables it.
set -x
Prints a trace of simple commands, for commands, case commands, select
commands, and arithmetic for commands and their arguments or
associated word lists after they are expanded and before they are
executed. The value of the PS4 variable is expanded and the resultant
value is printed before the command and its expanded arguments.
[source]
Example
set -x
echo `expr 10 + 20 `
+ expr 10 + 20
+ echo 30
30
set +x
echo `expr 10 + 20 `
30
Above example illustrates the usage of set -x. When it is used, above arithmetic expression has been expanded. We could see how a single line has been evaluated step by step.
First step expr has been evaluated.
Second step echo has been evaluated.
To know more about set → visit this link
when it comes to your shell script,
[ "$DEBUG" == 'true' ] && set -x
Your script might have been printing some additional lines of information when the execution mode selected as DEBUG. Traditionally people used to enable debug mode when a script called with optional argument such as -d
-u: disabled by default. When activated, an error message is displayed when using an unconfigured variable.
-v: inactive by default. After activation, the original content of the information will be displayed (without variable resolution) before the
information is output.
-x: inactive by default. If activated, the command content will be displayed before the command is run (after variable resolution, there
is a ++ symbol).
Compare the following differences:
/ # set -v && echo $HOME
/root
/ # set +v && echo $HOME
set +v && echo $HOME
/root
/ # set -x && echo $HOME
+ echo /root
/root
/ # set +x && echo $HOME
+ set +x
/root
/ # set -u && echo $NOSET
/bin/sh: NOSET: parameter not set
/ # set +u && echo $NOSET

Making Sublime Text 2 command on linux behave as it does on MacOS X

There are many questions asking about accessing the Sublime Text 2 editor from the command line. The responses, in summary, are to make a symlink, alias or simple shell script to run the appropriate sublime_text command. I can do that. What I want is to make the linux version behave like the MacOS version.
On MacOS, I have the following:
ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl ~/bin/subl
Then in my .zshrc:
alias subl="$HOME/bin/subl -n"
export EDITOR="$HOME/bin/subl -n -w"
This does two things. It gives me a subl command that opens any files given on the command line in a new window. The subl command does not block the terminal. It also sets up my editor to open sublime text to edit the arguments, but this time it does block. In particular, $EDITOR blocks until its arguments are closed. It does not block on unrelated sublime text windows.
I can achieve a similar effect on linux with the following:
In ~/bin/subl:
#! /bin/zsh
$HOME/Sublime\ Text\ 2/sublime_text -n $# &
and then in ~/bin/subl_wait: (think mate_wait for TextMate users)
#! /bin/zsh
exec $HOME/Sublime\ Text\ 2/sublime_text -n -w $#
I can then set EDITOR to subl_wait, and things almost work. subl opens files for editing and doesn't block. subl_wait opens files for editing and does block.
The problem is that subl_wait is waiting until all open files are closed, not just its arguments.
Is it possible to get this working perfectly?
Looks like I've found the issue. (Thanks to this post: http://www.sublimetext.com/forum/viewtopic.php?f=2&t=7003 )
Basic point: sublime behaves differently depending upon whether an instance is already running!
If an instance is already running then sublime on linux behaves similarly to MacOS. If no instance is running then the terminal blocks until you exit sublime.
With that in mind, we just need to modify the scripts to make sure sublime is running:
in ~/bin/subl_start:
#! /bin/zsh
if [ ! "$(pidof sublime_text)" ] ; then
# start sublime text main instance
# echo "Starting Sublime Text 2"
$HOME/Sublime\ Text\ 2/sublime_text &
sleep 1 # needed to avoid a race condition
fi
in ~/bin/subl:
#! /bin/zsh
. $HOME/bin/subl_start
exec $HOME/Sublime\ Text\ 2/sublime_text -n $#
in ~/bin/subl_wait:
#! /bin/zsh
. $HOME/bin/subl_start
exec $HOME/Sublime\ Text\ 2/sublime_text -n -w $#
Note that I've used the -n flags everywhere. This might not be your cup of tea. If you are using -n then you possibly also want to look at your close_windows_when_empty setting.
Inspired by the OP's answer, I've created a bash wrapper script for Sublime Text that incorporates all your findings and runs on both OSX and Linux.
Its purpose is threefold:
provide a unified subl CLI that works like ST's own subl on OSX: invoke ST without blocking, unless waiting is explicitly requested.
encapsulate a workaround for the waiting-related bug on Linux.
when saved or symlinked to as sublwait, provide a sublwait CLI that automatically applies the --wait and --new-window options so as to make it suitable for use with $EDITOR (note that some programs, e.g. npm, require the $EDITOR to contain the name of an executable only - executables + options are not supported); also makes sure that at least one file is specified.
The only open question is whether the OP's approach to avoiding the race condition - sleep 1 - is robust enough.
Update:
Note that subl on OSX is by default NOT placed in the $PATH - you normally have to do that manually. If you haven't done so, the script will now locate subl inside ST's application bundle; (it tries app names in the following sequence: 'Sublime Text', 'Sublime Text 2', 'Sublime Text 3', first in /Applications, then in ~/Applications.)
Here's the output from running the script with -h:
Multi-platform (OSX, Linux) wrapper script for invocation of Sublime Text (ST)
from the command line.
Linux:
Works around undesired blocking of the shell (unless requested)
and a bug when waiting for specific files to be edited.
Both platforms:
When invoked as `sublwait`, automatically applies the
--wait --new-window
options to make it suitable for use with $EDITOR.
Therefore, you can to the following:
- Name this script `subl` for a CLI that supports ALL options.
(On OSX, this will simply defer to the `subl` CLI that came with ST.)
- Place the script in a directory in your $PATH.
- In the same directory, create a symlink to the `subl` script named
`sublwait`:
ln -s subl sublwait
and, if desired, add
export EDITOR=sublwait
to your shell profile.
Note that if you only use OSX, you can make do with ST's own subl and just save this script directly as sublwait.
Script source:
#!/usr/bin/env bash
# Multi-platform (OSX, Linux) wrapper script for invocation of Sublime Text (ST)
# from the command line. Invoke with -h for details.
[[ $1 == '-h' || $1 == '--help' ]] && showHelpOnly=1 || showHelpOnly=0
[[ $(basename "$BASH_SOURCE") == 'sublwait' ]] && invokedAsSublWait=1 || invokedAsSublWait=0
[[ $(uname) == 'Darwin' ]] && isOsX=1 || isOsX=0
# Find the platform-appropriate ST executable.
if (( isOsX )); then # OSX: ST comes with a bona-fide CLI, `subl`.
# First, try to find the `subl` CLI in the $PATH.
# Note: This CLI is NOT there by default; it must be created by symlinking it from
# its location inside the ST app bundle.
# Find the `subl` executable, ignoring this script, if named subl' as well, or a
# script by that name in the same folder as this one (when invoked via symlink 'sublwait').
stExe=$(which -a subl | fgrep -v -x "$(dirname "$BASH_SOURCE")/subl" | head -1)
# If not already in the path, look for it inside the application bundle. Try several locations and versions.
if [[ -z $stExe ]]; then
for p in {,$HOME}"/Applications/Sublime Text"{,' 2',' 3'}".app/Contents/SharedSupport/bin/subl"; do
[[ -f $p ]] && { stExe=$p; break; }
done
fi
[[ -x $stExe ]] || { echo "ERROR: Sublime Text CLI 'subl' not found." 1>&2; exit 1; }
else # Linux: `sublime_text` is the only executable - the app itself.
stExe='sublime_text'
which "$stExe" >/dev/null || { echo "ERROR: Sublime Text executable '$stExe' not found." 1>&2; exit 1; }
fi
# Show command-line help, if requested.
# Add preamble before printing ST's own help.
# Note that we needn't worry about blocking the
# shell in this case - ST just outputs synchronously
# to stdout, then exits.
if (( showHelpOnly )); then
bugDescr=$(
cat <<EOF
works around a bug on Linux (as of v2.0.2), where Sublime Text,
if it is not already running, mistakenly blocks until it is exited altogether.
EOF
)
if (( invokedAsSublWait )); then
# We provide variant-specific help here.
cat <<EOF
Wrapper script for Sublime Text suitable for use with the \$EDITOR variable.
Opens the specified files for editing in a new window and blocks the
invoking program (shell) until they are closed.
In other words: the --wait and --new-window options are automatically
applied.
Aside from encapsulating this functionality without the need for options
- helpful for tools that require \$EDITOR to be an executable name only -
$bugDescr
Usage: sublwait file ...
EOF
# Note: Adding other options doesn't make sense in this scenario
# (as of v2.0.2), so we do NOT show ST's own help here.
else
cat <<EOF
Multi-platform (OSX, Linux) wrapper script for invocation of
Sublime Text (ST) from the command line.
Linux:
Works around undesired blocking of the shell (unless requested)
and a bug when waiting for specific files to be edited.
Both platforms:
When invoked as \`sublwait\`, automatically applies the
--wait --new-window
options to make it suitable for use with \$EDITOR.
Therefore, you can to the following:
- Name this script \`subl\` for a CLI that supports ALL options.
(On OSX, this will simply defer to the \`subl\` CLI that came with ST.)
- Place the script in a directory in your \$PATH.
- In the same directory, create a symlink to the \`subl\` script named
\`sublwait\`:
ln -s subl sublwait
and, if desired, add
export EDITOR=sublwait
to your shell profile.
Sublime Text's own help:
------------------------
EOF
# Finally, print ST's own help and exit.
exec "$stExe" "$#"
fi
exit 0
fi
# Invoked as `sublwait`? -> automatically apply --wait --new-window options.
if (( invokedAsSublWait )); then
# Validate parameters.
# - We expect NO options - to keep things simple and predictable, we do NOT allow
# specifying additional options (beyond the implied ones).
# - We need at least 1 file argument.
# - As a courtesy, we ensure that no *directories* are among the arguments - ST doesn't support
# that properly (always waits for ST exit altogether); beyond that, however, we leave input
# validation to ST.
if [[ "$1" =~ ^-[[:alnum:]]+$ || "$1" =~ ^--[[:alnum:]]+[[:alnum:]-]+$ ]]; then # options specified?
{ echo "ERROR: Unexpected option specified: '$1'. Use -h for help." 1>&2; exit 1; }
elif (( $# == 0 )); then # no file arguments?
{ echo "ERROR: Missing file argument. Use -h for help." 1>&2; exit 1; }
else # any directories among the arguments?
# Note: We do NOT check for file existence - files could be created on demand.
# (Things can still go wrong - e.g., /nosuchdir/mynewfile - and ST doesn't
# handle that gracefully, but we don't want to do too much here.)
for f in "$#"; do
[[ ! -d "$f" ]] || { echo "ERROR: Specifying directories is not supported: '$f'. Use -h for help." 1>&2; exit 1; }
done
fi
# Prepend the implied options.
set -- '--wait' '--new-window' "$#"
fi
# Finally, invoke ST:
if (( isOsX )); then # OSX
# `subl` on OSX handles all cases correctly; simply pass parameters through.
exec "$stExe" "$#"
else # LINUX: `sublime_text`, the app executable itself, does have a CLI, but it blocks the shell.
# Determine if the wait option was specified.
mustWait=0
if (( invokedAsSublWait )); then
mustWait=1
else
# Look for the wait option in the parameters to pass through.
for p in "$#"; do
[[ $p != -* ]] && break # past options
[[ $p == '--wait' || $p =~ ^-[[:alnum:]]*w[[:alnum:]]*$ ]] && { mustWait=1; break; }
done
fi
if (( mustWait )); then # Invoke in wait-for-specified-files-to-close mode.
# Quirk on Linux:
# If sublime_text isn't running yet, we must start it explicitly first.
# Otherwise, --wait will wait for ST *as a whole* to be closed before returning,
# which is undesired.
# Thanks, http://stackoverflow.com/questions/14598261/making-sublime-text-2-command-on-linux-behave-as-it-does-on-macos-x
if ! pidof "$stExe" 1>/dev/null; then
# Launch as BACKGROUND task to avoid blocking.
# (Sadly, the `--background` option - designed not to activate the Sublime Text window
# on launching - doesn't actually work on Linux (as of ST v2.0.2 on Ubuntu 12.04).)
("$stExe" --background &)
# !! We MUST give ST some time to start up, otherwise the 2nd invocation below will be ignored.
# ?? Does a fixed sleep time of 1 second work reliably?
sleep 1
fi
# Invoke in blocking manner, as requested.
exec "$stExe" "$#"
else # Ensure invocation in NON-blocking manner.
if ! pidof "$stExe" 1>/dev/null; then # ST isn't running.
# If ST isn't running, invoking it *always* blocks.
# Therefore, we launch it as a background taks.
# Invocation via a subshell (parentheses) suppresses display of the
# background-task 'housekeeping' info.
("$stExe" "$#" &)
else # ST is already running, we can safely invoke it directly without fear of blocking.
exec "$stExe" "$#"
fi
fi
fi
On Ubuntu Gnu/Linux 13.04 64-bit:
I just keep subl running pretty much all the time. So my git config has:
core.editor=/usr/bin/subl -n -w
And that's all I need. I save the git commit file with ctrl-s, close the window with ctrl-w and I'm done. But I then have to really close the window by hitting the X in the upper corner... 96% perfect.

current directory doesn't appear in title bar when running under screen

My xterm $prompt variable in my .tcshrc is:
set prompt="%{\033]0;%m:%~\007%}%{^[[;37;1m%}%B%{^[[;34;1m%}%m%{^[[;34;1m%}:%b%c%# "
The highlighted part above (%{\033]0;%m:%~\007%}) puts the hostname (%m) and the current directory (%~) in the title bar. (At least I think that that's what puts it in the title bar; it's been a while since I fiddled with this prompt).
When I run screen, however, the current directory stops getting updated when I change directories.
My questions:
How can I make this prompt work in screen?
Is there a better way to display the current directory in the title bar?
I am running linux with xterm and tcsh.
I think there is no direct way, because of the way screen works. However screen can display its own status bar, that you can define in .screenrc. Here's mine for instance :
hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][%=%{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B}%Y-%m-%d %{W}%c %{g}]'
Firstly, to make it work you must check where exactly is the line with set prompt=blah-blah in your .tcshrc. For example, the code below that perfectly works in plain xterm would not work under screen in xterm:
switch ($TERM)
case "xterm*":
set prompt="%{\033]0;${HOME:t}#%m:%l:%c08\007%}%{\033[36m%}%l:%c02%#%{\033[0m%} "
# update xterm title to display current cmd in it
alias postcmd 'echo -n "\033]0;${HOME:t}#`hostname`:${tty} \!#:q\007"'
...
because screen by default sets $TERM variable to screen and not xterm! So you must add:
case "screen":
# lame, but prevents an error in screen after 'su - root'
if (! $?WINDOW) setenv WINDOW 1
set prompt="%{\033]0;${HOME:t}#%m:${WINDOW}:%c08\007%}%{\033[36m%}%c02%#%{\033[0m%} "
alias postcmd 'echo -n "\033]0;${HOME:t}#`hostname`:${WINDOW} \!#:q\007"'
...
Secondly, make sure yo have this line in ~/.screenrc:
termcapinfo xterm* 'hs:ts=\E]2;:fs=\007:ds=\E]2;\007'

Resources