我已经使用bash两年了,只是试图通过自制软件在我的OS X上切换到zsh shell。我将我的默认(登录)shell设置为zsh,并且通过查看当我启动终端时,我确认它设置正确,它是默认使用的zsh shell。
但是,当我尝试从zsh中输入bash shell时,看起来好像没有加载~/.bash_profile
,因为我无法使用别名来运行我的命令,别名在我的~/.bash_profile
{{1}中定义此外,提示不是我在文件中设置的,而是返回alias julia="~/juila/julia"
。
由于某些原因,当我将登录shell设置为bash并从bash中输入zsh时,bash-3.2$
被正确加载。
那么为什么每当我从zsh中运行~/.zshrc
时它都没有被加载?我的bash
符号链接到~/.bash_profile
,以便与其他计算机同步。也许它会引起这个问题?
答案 0 :(得分:23)
互动式bash
会在~/.bash_profile
(如果它是登录shell)或~/.bashrc
(如果它不是登录shell)时读取。
典型的.bash_profile
将包含以下内容:
if [ -f ~/.bashrc ]; then . ~/.bashrc; fi
所以.bashrc
可以包含由登录或非登录shell执行的命令。
如果您运行的是bash -l
,而不仅仅是bash
,则应该会看到.bash_profile
。
参考:https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
答案 1 :(得分:18)
补充@Keith Thompson的优秀答案:
<强> MACOS 强>:
作为@chepner puts it succinctly(强调我的):
在OS X中,bash不用作初始[启动时]登录过程的一部分,并且Terminal.app(或其他终端仿真程序)进程存在于任何预先存在的bash会话之外,因此每个新窗口[或标签 - 读取:交互式bash shell](默认情况下)将自己视为新的登录会话。
因此,某些OSX用户只创建~/.bash_profile
,而且从不打扰~/.bashrc
,因为所有交互式bash shell都是 login 壳。
<强>的Linux 强>:
在Linux上,情况通常是颠倒:
交互式创建的bash
shell是[交互式] 非登录 shell,因此~/.bashrc
非常重要。
因此,许多Linux用户只处理~/.bashrc
。
要维护适用于两种平台的 bash配置文件,请使用@Keith Thompson提及的技术:
~/.bashrc
~/.bash_profile
[[ -f ~/.bashrc ]] && . ~/.bashrc
答案 2 :(得分:16)
打开~/.zshrc
,在文件的最底部添加以下内容:
if [ -f ~/.bash_profile ]; then
. ~/.bash_profile;
fi
每次打开终端时,它都会加载~/.bash_profile
中定义的任何内容(如果文件存在)。这样,您就可以保留 zsh (颜色等)的自定义设置。您可以在.bash_profile
文件中保留自定义shell设置。
这比使用bash -l
IMO要清晰得多。
如果您希望将设置放在.bashrc
,.bash_login
或.profile
中,则可以为他们执行相同操作。
答案 3 :(得分:12)
复制〜/ .bash_profile中的内容并将其粘贴到〜/ .zshrc文件的底部。
答案 4 :(得分:8)
对于刚刚安装zsh并希望其bash别名在zsh上运行的用户,请执行以下操作
像这样在vim中打开.zshrc文件
vi ~/.zshrc
滚动到底部
source ~/.bash_profile
:wq
source ~/.zshrc
而已。现在,您在.bash_profile中保存的所有别名都可以在zsh中使用了。答案 5 :(得分:6)
对于MacO上的ZSH用户,我最终得到了一个内线。
在 〜/ .zshrc 的最底部,我添加了以下行:
bash -l
它的作用只是加载 .bash_profile 设置(别名,函数,导出$ PATH,...)
如果你决定摆脱ZSH并回到原来的BASH,你将恢复正常,没有任何麻烦。
答案 6 :(得分:3)
如果您不经常这样做,或者它不适合进行更改,您也可以来源&#39;启动子bash shell后, .bash_profile 。
. ~/.bash_profile
这将在 .bash_profile 脚本中提取您在该shell会话生命周期内所做的设置。在大多数情况下,您应该能够重复该命令,因此它也是一种简单的方法来测试您所做的任何更改,而无需进行完全登录,并且可以将所有现有的shell会话 - 如果您升级到 .bash_profile &amp; /或 .bashrc 文件,则为目前为止。
答案 7 :(得分:1)
最近我在OS X上安装了oh-my-zsh,并将i
设置为默认外壳,并遇到了同样的问题。
我通过在#!/usr/bin/env python3
# command line interface (CLI) parsing
import requests
import argparse
import datetime
import time
import datetime
from pprint import pprint
# graphical user interface (GUI)
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import GLib
from gi.repository.GdkPixbuf import Pixbuf, Colorspace # for images
from gi.repository import Gio
from io import BytesIO
# DICOM
from dicomweb_client.api import DICOMwebClient
# this directory
def try_get_attr(data, tag, default_value=None):
'''Try get attribute indexed by TAG in DICOM data DATA.'''
try:
value = data[tag]['Value'][0]
if data[tag]['vr'] == 'US': # unsigned int
return value # return integer
elif data[tag]['vr'] == 'DA': # date
return datetime.date(int(value[0 : 4]),
int(value[4 : 6]),
int(value[6 : 8]))
elif data[tag]['vr'] == 'TM': # time (of day)
return datetime.time(int(value[0 : 2]),
int(value[2 : 4]),
int(value[4 : 6]))
else:
return value # as is
except:
return default_value
def try_get_attr_alphabetic(data, tag, default_value=None):
try:
return try_get_attr(data, tag, default_value)['Alphabetic']
except:
return default_value
class StudyStore(Gtk.ListStore):
'''Gtk.ListStore of DICOM studies (model).'''
def __init__(self, client):
Gtk.ListStore.__init__(self, str, str, str, str, str) # TODO GDate, GTime
self.client = client
studies = self.client.search_for_studies()
for study in studies:
study_instance_uid = try_get_attr(study, '0020000D') # TODO wrap in DicomUID when 'vr': 'UI'
if study_instance_uid is None:
continue # skip because http://dev-demo.sectra.se contains lots of such entries
study_name = try_get_attr(study, '00100020') # TODO decode string when 'vr': 'LO'
person_name = try_get_attr_alphabetic(study, '00100010') # TODO decode Person Name string when 'vr': 'PN'
study_date = str(try_get_attr(study, '00080020')) # TODO GDate
study_time = str(try_get_attr(study, '00080030')) # TODO GTime
# studies_id = try_get_attr(study, '00020010') # TODO 'vr' : 'UI'. same for all elements in `studies`
# study = client.retrieve_study(study_instance_uid) # retrieve same thing again
self.append((study_instance_uid, study_name, person_name, study_date, study_time))
class SeriesStore(Gtk.ListStore):
'''Gtk.ListStore of DICOM serieses (model).'''
def __init__(self, client):
Gtk.ListStore.__init__(self, str, str)
self.client = client
def update_using_study(self, study_instance_uid):
self.study_instance_uid = study_instance_uid
self.serieses = self.client.search_for_series(study_instance_uid)
for series in self.serieses:
series_instance_uid = try_get_attr(series, '0020000E') # Series Instance UID
series_modality = try_get_attr(series, '00080060') # Modality being either CR, OT, MR, XA, CT, US
self.append((series_instance_uid, series_modality))
class InstanceStore(Gtk.ListStore):
'''Gtk.ListStore of DICOM instances (model).'''
def __init__(self, client):
Gtk.ListStore.__init__(self, str, str)
self.client = client
def update_using_study_and_series(self, study_instance_uid, series_instance_uid):
instances = self.client.search_for_instances(study_instance_uid,
series_instance_uid)
for instance in instances:
sop_class_uid = try_get_attr(instance, '00080016') # SOP Class UID
try:
sop_name = SOP_UID_NAMES[sop_class_uid] # lookup SOP name from UID
except:
sop_name = sop_class_uid # if fails use UID
sop_instance_uid = try_get_attr(instance, '00080018') # SOP Instance UID
self.append((sop_instance_uid, sop_name))
class DICOMWindow(Gtk.Window):
def __init__(self, title="DICOM Viewer"):
self.client = DICOMwebClient(url="https://dicomcloud.azurewebsites.net",
qido_url_prefix="qidors",
wado_url_prefix="wadors",
stow_url_prefix="stowrs")
# construct top window
Gtk.Window.__init__(self,
title=title,
vexpand=True, hexpand=True,
border_width=0)
# create top grid
self.grid = Gtk.Grid(vexpand=True, hexpand=True,
column_homogeneous=True,
row_homogeneous=True)
self.add(self.grid) # add it to parent window
# STUDIES
self.study_store = StudyStore(client=self.client)
self.current_study_filter = None
self.study_filter = self.study_store.filter_new()
self.study_filter.set_visible_func(self.study_view_filter_func)
self.study_view = Gtk.TreeView.new_with_model(self.study_filter)
self.study_selection = self.study_view.get_selection()
self.study_selection.set_mode(Gtk.SelectionMode.MULTIPLE)
self.study_selection.connect("changed", self.on_study_view_selection_changed)
for i, column_title in enumerate(["Study UID", "Study Name", "Person Name", "Study Date", "Study Time",]):
if i == 0:
continue # skip "Study UID"
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
self.study_view.append_column(column)
self.study_view_scroller = Gtk.ScrolledWindow(vexpand=True,
hexpand=True)
self.study_view_scroller.add(self.study_view)
self.grid.attach(self.study_view_scroller,
left=0, top=0, width=1, height=1)
# SERIESES
self.series_store = SeriesStore(client=self.client)
self.current_series_filter = None
self.series_filter = self.series_store.filter_new()
self.series_filter.set_visible_func(self.series_view_filter_func)
self.series_view = Gtk.TreeView.new_with_model(self.series_filter)
self.series_selection = self.series_view.get_selection()
self.series_selection.set_mode(Gtk.SelectionMode.MULTIPLE)
self.series_selection.connect("changed", self.on_series_view_selection_changed)
for i, column_title in enumerate(["Series UID", "Series Modality"]):
if i == 0:
continue # skip "Series UID"
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
self.series_view.append_column(column)
self.series_view_scroller = Gtk.ScrolledWindow(vexpand=True,
hexpand=True)
self.series_view_scroller.add(self.series_view)
self.grid.attach(self.series_view_scroller,
left=1, top=0, width=1, height=1)
# INSTANCES
self.instance_store = InstanceStore(client=self.client)
self.current_instance_filter = None
self.instance_filter = self.instance_store.filter_new()
self.instance_filter.set_visible_func(self.instance_view_filter_func)
self.instance_view = Gtk.TreeView.new_with_model(self.instance_filter)
self.instance_selection = self.instance_view.get_selection()
self.instance_selection.set_mode(Gtk.SelectionMode.MULTIPLE)
self.instance_selection.connect("changed", self.on_instance_view_selection_changed)
for i, column_title in enumerate(["SOP Instance UID", "SOP Class"]):
if i == 0:
continue # skip "SOP Instance UID"
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
self.instance_view.append_column(column)
self.instance_view_scroller = Gtk.ScrolledWindow(vexpand=True,
hexpand=True)
self.instance_view_scroller.add(self.instance_view)
self.grid.attach(self.instance_view_scroller,
left=2, top=0, width=1, height=1)
self.image_view = Gtk.Image()
self.image_view_scroller = Gtk.ScrolledWindow(vexpand=True,
hexpand=True)
self.image_view_scroller.add(self.image_view)
self.grid.attach(self.image_view_scroller,
left=0, top=1, width=3, height=3)
self.show_all()
def on_study_view_selection_changed(self, selection):
print('on_study_view_selection_changed: selection_count=', selection.count_selected_rows())
# needs to be called in this order
self.clear_current_image_and_pixel_data()
self.clear_current_instance_store_and_view()
self.clear_current_series_store_and_view()
model, treeiter = selection.get_selected_rows()
for row_index in treeiter:
self.study_instance_uid = model[row_index][0]
self.series_store.update_using_study(study_instance_uid=self.study_instance_uid)
# TODO visually present:
# study_metadata = self.client.retrieve_study_metadata(self.study_instance_uid)
def on_series_view_selection_changed(self, selection):
print('on_series_view_selection_changed: selection_count=', selection.count_selected_rows())
# needs to be called in this order
self.clear_current_image_and_pixel_data()
self.clear_current_instance_store_and_view()
model, treeiter = selection.get_selected_rows()
for row_index in treeiter:
self.series_instance_uid = model[row_index][0]
self.instance_store.update_using_study_and_series(study_instance_uid=self.study_instance_uid,
series_instance_uid=self.series_instance_uid)
# TODO visually present:
# series_metadata = self.client.retrieve_series_metadata(self.study_instance_uid,
# self.series_instance_uid)
def on_instance_view_selection_changed(self, selection):
print('on_instance_view_selection_changed: selection_count=', selection.count_selected_rows())
# needs to be called in this order
self.clear_current_image_and_pixel_data()
model, treeiter = selection.get_selected_rows()
for row_index in treeiter:
self.sop_instance_uid = model[row_index][0]
# TODO visually present more parts of:
instance_metadata = self.client.retrieve_instance_metadata(study_instance_uid=self.study_instance_uid,
series_instance_uid=self.series_instance_uid,
sop_instance_uid=self.sop_instance_uid)[0]
self.image_height = try_get_attr(instance_metadata, '00280010') # rows
self.image_width = try_get_attr(instance_metadata, '00280011') # columns
self.image_bits_per_pixel = try_get_attr(instance_metadata, '00280100') # bits per pixel
self.frame_count = try_get_attr(instance_metadata, '00280008', '1') # only present for multi-frame image instances so default to 1
transfer_syntax_uid = try_get_attr(instance_metadata, '00020010')
if transfer_syntax_uid is not None:
transfer_type = transfer_syntax_uid
image_format = None # possible values are None (uncompressed/raw), 'jpeg', or 'jp2'
try:
# start = time.time()
frames = self.client.retrieve_instance_frames(study_instance_uid=self.study_instance_uid,
series_instance_uid=self.series_instance_uid,
sop_instance_uid=self.sop_instance_uid,
frame_numbers=[1],
image_format=image_format)
# stop = time.time()
# print("Took:", stop - start)
except requests.exceptions.HTTPError:
frames = [] # no frames
pass
# need to store frames because Pixbuf.new_from_data doesn't keep own
# reference to data so Python will destroy it without Gtk knowing about it
self.rgb_frames = len(frames)*[None]
for image_index, frame in enumerate(frames):
pixel_count = (self.image_width* self.image_height)
rgb_frame_temp = bytearray(3*pixel_count) # pre-allocate RGB pixels
if image_format is None: # raw pixels
if self.image_bits_per_pixel == 8:
for j in range(0, pixel_count):
gray8 = frame[j]
rgb_frame_temp[3*j + 0] = gray8
rgb_frame_temp[3*j + 1] = gray8
rgb_frame_temp[3*j + 2] = gray8
else:
raise Exception("Cannot handle bits_per_pixel being" +
str(self.image_bits_per_pixel))
# Ref: https://lazka.github.io/pgi-docs/#GdkPixbuf-2.0/classes/Pixbuf.html#GdkPixbuf.Pixbuf.new_from_data
# this better than `Pixbuf.new_from_bytes` which requires
# the data parameter to be wrapped in a GLib.Bytes object
# WARNING: be aware of that `new_from_data` is buggy. See for instance:
# https://stackoverflow.com/questions/29501835/gtk3-gdk-pixbuf-new-from-data-gives-segmentation-fault-core-dumped-error-13
self.rgb_frames[image_index] = bytes(rgb_frame_temp) # bytearray needs to be wrapped in a `bytes` and store here in order to enot loose ref
pixbuf = Pixbuf.new_from_data(self.rgb_frames[image_index], # data
Colorspace.RGB, # colorspace
False, # has_alpha
8, # bits_per_sample
self.image_width, # width
self.image_height, # height
self.image_width*3, # rowstride, 3 because RGB has 3 bytes per pixel
None, None) # rely on Python for deallocation
if image_index == 0:
self.image_view.set_from_pixbuf(pixbuf)
elif image_format == 'jp2':
print("TODO Decode jp2 image...")
if False:
input_stream = Gio.MemoryInputStream.new_from_data(frame, None)
pixbuf = Pixbuf.new_from_stream(input_stream, None)
if image_index == 0:
self.image_view.set_from_pixbuf(pixbuf)
def clear_current_series_store_and_view(self):
self.series_store.clear()
self.series_view.get_selection().unselect_all()
def clear_current_instance_store_and_view(self):
self.instance_store.clear()
self.instance_view.get_selection().unselect_all()
def clear_current_image_and_pixel_data(self):
self.image_view.clear() # remove image before
self.rgb_frames = None # drop pixel data
def study_view_filter_func(self, model, iter, data):
"""Tests if the language in the row is the one in the filter"""
if self.current_study_filter is None or self.current_study_filter == "Any":
return True
else:
return model[iter][2] == self.current_study_filter
def series_view_filter_func(self, model, iter, data):
"""Tests if the language in the row is the one in the filter"""
if self.current_series_filter is None or self.current_series_filter == "Any":
return True
else:
return model[iter][2] == self.current_series_filter
def instance_view_filter_func(self, model, iter, data):
"""Tests if the language in the row is the one in the filter"""
if self.current_instance_filter is None or self.current_instance_filter == "Any":
return True
else:
return model[iter][2] == self.current_instance_filter
if __name__ == '__main__':
win = DICOMWindow()
win.connect("destroy", Gtk.main_quit) # make close button window work
win.show_all() # show everything
Gtk.main() # start event loop
文件的末尾添加zsh
来solved这个问题。
答案 8 :(得分:1)
我正在使用一个名为oh my zsh的zsh框架,并且尝试了此处列出的大多数解决方案,但它破坏了自定义主题的格式。但是,这些步骤对我有用。
在我的 .bash_profile
底部添加新别名 vi ~/.bash_profile
使用 zsh 从 .bash_profile
加载项目 source ~/.bash_profile
刷新 zsh
source ~/.zshrc
重新启动OSX Terminal应用程序
尝试您的新别名!
答案 9 :(得分:0)
如果您想“以个人资料为中心”,您可以创建 .profile
作为单一的事实来源,然后从 .bash_profile
和 .zprofile
加载它。>
.profile
export PATH="/usr/local/opt/python/libexec/bin:$PATH"
# etc., etc.
.bash_profile 和 .zprofile
if [ -f ~/.profile ]; then
. ~/.profile;
fi
我发现这有助于 bash 脚本找到正确的 PATH
等,并帮助我将配置保存在一个地方。