Various fixes

This commit is contained in:
crschnick
2025-08-19 13:06:16 +00:00
parent 5382c23066
commit 05c0409005
29 changed files with 189 additions and 52 deletions
@@ -15,10 +15,7 @@ import java.util.Optional;
public abstract class AppShellChecker {
public void check() throws Exception {
var canFallback = !ProcessControlProvider.get()
.getEffectiveLocalDialect()
.equals(ProcessControlProvider.get().getFallbackDialect());
var canFallback = !ProcessControlProvider.get().canFallback();
if (canFallback && fallBackInstantly()) {
toggleFallback();
canFallback = false;
@@ -60,9 +57,7 @@ public abstract class AppShellChecker {
}
private String formatMessage(String output) {
var fallback = !ProcessControlProvider.get()
.getEffectiveLocalDialect()
.equals(ProcessControlProvider.get().getFallbackDialect())
var fallback = ProcessControlProvider.get().canFallback()
? AppNames.ofCurrent().getName() + " will now attempt to fall back to another shell."
: "";
return """
@@ -10,6 +10,7 @@ import io.xpipe.app.process.ShellDialect;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.vnc.VncBaseStore;
import java.util.List;
import java.util.ServiceLoader;
public abstract class ProcessControlProvider {
@@ -46,11 +47,21 @@ public abstract class ProcessControlProvider {
public abstract ShellDialect getEffectiveLocalDialect();
public ShellDialect getNextFallbackDialect() {
var av = getAvailableLocalDialects();
var index = av.indexOf(getEffectiveLocalDialect());
var next = (index + 1) % av.size();
return av.get(next);
}
public abstract void toggleFallbackShell();
public abstract ShellDialect getDefaultLocalDialect();
public abstract List<ShellDialect> getAvailableLocalDialects();
public abstract ShellDialect getFallbackDialect();
public boolean canFallback() {
var av = getAvailableLocalDialects();
return av.indexOf(getEffectiveLocalDialect()) < av.size() - 1;
}
public abstract <T extends DataStore> DataStoreEntryRef<T> replace(DataStoreEntryRef<T> ref);
@@ -0,0 +1,99 @@
package io.xpipe.app.ext;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.process.ShellDialect;
import io.xpipe.app.process.ShellDialects;
import javafx.beans.property.Property;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Region;
import lombok.AllArgsConstructor;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
@AllArgsConstructor
public class ShellDialectChoiceComp extends SimpleComp {
public enum NullHandling {
NULL_IS_DEFAULT,
NULL_IS_ALL,
NULL_DISABLED
}
public static final Map<ShellDialect, String> ICONS = new LinkedHashMap<>();
static {
ICONS.put(ShellDialects.CMD, "cmd_icon.svg");
ICONS.put(ShellDialects.POWERSHELL, "powershell_logo.svg");
ICONS.put(ShellDialects.POWERSHELL_CORE, "pwsh_logo.png");
ICONS.put(ShellDialects.SH, "sh_icon.svg");
ICONS.put(ShellDialects.ASH, "sh_icon.svg");
ICONS.put(ShellDialects.DASH, "sh_icon.svg");
ICONS.put(ShellDialects.BASH, "bash_icon.svg");
ICONS.put(ShellDialects.FISH, "fish_icon.svg");
ICONS.put(ShellDialects.ZSH, "zsh_icon.svg");
ICONS.put(ShellDialects.NUSHELL, "nushell_icon.svg");
ICONS.put(ShellDialects.XONSH, "xonsh_icon.png");
}
private final List<ShellDialect> available;
private final Property<ShellDialect> selected;
private final NullHandling nullHandling;
public static String getImageName(ShellDialect t) {
if (t == null) {
return "proc:defaultShell_icon.svg";
}
return "proc:" + ICONS.get(t);
}
@Override
protected Region createSimple() {
Supplier<ListCell<ShellDialect>> supplier = () -> new ListCell<>() {
@Override
protected void updateItem(ShellDialect item, boolean empty) {
super.updateItem(item, empty);
setText(item != null ? item.getDisplayName() : nullHandling == NullHandling.NULL_IS_ALL ? AppI18n.get("all") : AppI18n.get("default"));
setGraphic(
item != null
? PrettyImageHelper.ofFixedSizeSquare("proc:" + ICONS.get(item), 16)
.createRegion()
: PrettyImageHelper.ofFixedSizeSquare("proc:defaultShell_icon.svg", 16)
.createRegion());
}
};
var cb = new ComboBox<ShellDialect>();
cb.setCellFactory(param -> supplier.get());
cb.setButtonCell(supplier.get());
cb.setValue(selected.getValue());
selected.bind(cb.valueProperty());
cb.setOnKeyPressed(event -> {
if (!event.getCode().equals(KeyCode.ENTER)) {
return;
}
cb.show();
event.consume();
});
if (nullHandling != NullHandling.NULL_DISABLED) {
cb.getItems().add(null);
}
cb.getItems().addAll(available);
cb.setVisibleRowCount(available.size() + 1);
cb.getStyleClass().add("choice-comp");
cb.setMaxWidth(20000);
return cb;
}
}
@@ -216,9 +216,9 @@ public class SentryErrorHandler implements ErrorHandler {
s.setTag("diagnostics", Boolean.toString(ee.isShouldSendDiagnostics()));
s.setTag("licenseRequired", Boolean.toString(ee.getThrowable() instanceof LicenseRequiredException));
s.setTag(
"fallbackShell",
AppPrefs.get() != null
? String.valueOf(AppPrefs.get().useLocalFallbackShell().get())
"localShell",
AppPrefs.get() != null && AppPrefs.get().localShellDialect().getValue() != null
? AppPrefs.get().localShellDialect().getValue().getId()
: "unknown");
s.setTag("initial", AppProperties.get() != null ? AppProperties.get().isInitialLaunch() + "" : "false");
@@ -4,8 +4,10 @@ import io.xpipe.app.core.*;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.ext.PrefsHandler;
import io.xpipe.app.ext.PrefsProvider;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.icon.SystemIconManager;
import io.xpipe.app.icon.SystemIconSource;
import io.xpipe.app.process.ShellDialect;
import io.xpipe.app.process.ShellScript;
import io.xpipe.app.pwman.PasswordManager;
import io.xpipe.app.rdp.ExternalRdpClient;
@@ -129,6 +131,14 @@ public final class AppPrefs {
mapLocal(new GlobalBooleanProperty(false), "disableCertutilUse", Boolean.class, false);
public final BooleanProperty useLocalFallbackShell =
mapLocal(new GlobalBooleanProperty(false), "useLocalFallbackShell", Boolean.class, true);
final Property<ShellDialect> localShellDialect = map(Mapping.builder()
.property(new GlobalObjectProperty<>(ProcessControlProvider.get().getAvailableLocalDialects().getFirst()))
.key("localShellDialect")
.valueClass(ShellDialect.class)
.vaultSpecific(false)
.requiresRestart(true)
.build());
public final BooleanProperty disableTerminalRemotePasswordPreparation = mapVaultShared(
new GlobalBooleanProperty(false), "disableTerminalRemotePasswordPreparation", Boolean.class, false);
public final Property<Boolean> alwaysConfirmElevation =
@@ -509,6 +519,10 @@ public final class AppPrefs {
return useLocalFallbackShell;
}
public ObservableValue<ShellDialect> localShellDialect() {
return localShellDialect;
}
public ObservableBooleanValue disableTerminalRemotePasswordPreparation() {
return disableTerminalRemotePasswordPreparation;
}
@@ -669,6 +683,15 @@ public final class AppPrefs {
.orElse(false)) {
useSystemFont.set(false);
}
if (useLocalFallbackShell.get()) {
localShellDialect.setValue(ProcessControlProvider.get().getAvailableLocalDialects().get(1));
useLocalFallbackShell.set(false);
}
if (localShellDialect.getValue() == null || !ProcessControlProvider.get().getAvailableLocalDialects().contains(localShellDialect.getValue())) {
localShellDialect.setValue(ProcessControlProvider.get().getAvailableLocalDialects().getFirst());
}
}
public OptionsBuilder getCustomOptions(String id) {
@@ -3,9 +3,13 @@ package io.xpipe.app.prefs;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.ChoiceComp;
import io.xpipe.app.ext.PrefsChoiceValue;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.ext.ShellDialectChoiceComp;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.OptionsBuilder;
import java.util.List;
public class SystemCategory extends AppPrefsCategory {
@Override
@@ -21,8 +25,6 @@ public class SystemCategory extends AppPrefsCategory {
public Comp<?> create() {
var prefs = AppPrefs.get();
var builder = new OptionsBuilder();
var localShellBuilder =
new OptionsBuilder().pref(prefs.useLocalFallbackShell).addToggle(prefs.useLocalFallbackShell);
builder.addTitle("system")
.sub(new OptionsBuilder()
.pref(prefs.startupBehaviour)
@@ -36,9 +38,10 @@ public class SystemCategory extends AppPrefsCategory {
prefs.closeBehaviour,
PrefsChoiceValue.getSupported(CloseBehaviour.class),
false)
.maxWidth(getCompWidth())));
builder.sub(localShellBuilder);
builder.sub(new OptionsBuilder().pref(prefs.developerMode).addToggle(prefs.developerMode));
.maxWidth(getCompWidth()))
.pref(prefs.localShellDialect).addComp(new ShellDialectChoiceComp(ProcessControlProvider.get().getAvailableLocalDialects(), prefs.localShellDialect, ShellDialectChoiceComp.NullHandling.NULL_DISABLED).maxWidth(getCompWidth()),
prefs.localShellDialect)
.pref(prefs.developerMode).addToggle(prefs.developerMode));
return builder.buildComp();
}
}
@@ -140,8 +140,6 @@ public interface ShellControl extends ProcessControl {
@Override
LocalProcessInputStream getStderr();
ShellControl withErrorFormatter(Function<String, String> formatter);
void checkLicenseOrThrow();
String prepareIntermediateTerminalOpen(
@@ -292,11 +292,6 @@ public class WrapperShellControl implements ShellControl {
return parent.getStderr();
}
@Override
public ShellControl withErrorFormatter(Function<String, String> formatter) {
return parent.withErrorFormatter(formatter);
}
@Override
public void checkLicenseOrThrow() {
parent.checkLicenseOrThrow();
@@ -6,11 +6,7 @@ import io.xpipe.app.comp.base.ListSelectorComp;
import io.xpipe.app.core.AppExtensionManager;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppNames;
import io.xpipe.app.ext.DataStore;
import io.xpipe.app.ext.DataStoreCreationCategory;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.EnabledParentStoreProvider;
import io.xpipe.app.ext.GuiDialog;
import io.xpipe.app.ext.*;
import io.xpipe.app.hub.comp.*;
import io.xpipe.app.process.OsFileSystem;
import io.xpipe.app.process.ShellDialect;
@@ -93,14 +89,7 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da
ShellDialects.CMD,
ShellDialects.POWERSHELL,
ShellDialects.POWERSHELL_CORE);
Comp<?> choice = (Comp<?>) Class.forName(
AppExtensionManager.getInstance()
.getExtendedLayer()
.findModule(AppNames.extModuleName("proc"))
.orElseThrow(),
AppNames.extModuleName("proc") + ".ShellDialectChoiceComp")
.getDeclaredConstructor(List.class, Property.class, boolean.class)
.newInstance(availableDialects, dialect, true);
Comp<?> choice = new ShellDialectChoiceComp(availableDialects, dialect, ShellDialectChoiceComp.NullHandling.NULL_IS_ALL);
var vals = List.of(0, 1, 2, 3);
var selectedStart = new ArrayList<Integer>();
@@ -252,14 +241,7 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da
}
SimpleScriptStore st = store.asNeeded();
return (String) Class.forName(
AppExtensionManager.getInstance()
.getExtendedLayer()
.findModule(AppNames.extModuleName("proc"))
.orElseThrow(),
AppNames.extModuleName("proc") + ".ShellDialectChoiceComp")
.getDeclaredMethod("getImageName", ShellDialect.class)
.invoke(null, st.getMinimumDialect());
return ShellDialectChoiceComp.getImageName(st.getMinimumDialect());
}
@Override
@@ -147,8 +147,7 @@ public class IncusCommandView extends CommandViewBase {
var sub = shellControl.subShell();
sub.setDumbOpen(createOpenFunction(container, user, false, busybox));
sub.setTerminalOpen(createOpenFunction(container, user, true, busybox));
return sub.withErrorFormatter(IncusCommandView::formatErrorMessage)
.withExceptionConverter(IncusCommandView::convertException)
return sub.withExceptionConverter(IncusCommandView::convertException)
.elevated(requiresElevation());
}
@@ -169,8 +169,7 @@ public class LxdCommandView extends CommandViewBase {
var sub = shellControl.subShell();
sub.setDumbOpen(createOpenFunction(container, user, false, busybox));
sub.setTerminalOpen(createOpenFunction(container, user, true, busybox));
return sub.withErrorFormatter(LxdCommandView::formatErrorMessage)
.withExceptionConverter(LxdCommandView::convertException)
return sub.withExceptionConverter(LxdCommandView::convertException)
.elevated(requiresElevation());
}
@@ -18,7 +18,7 @@ public class PodmanCommandView extends CommandViewBase {
}
private static String formatErrorMessage(String s) {
return "Podman connection failed:\n" + s;
return s;
}
private static <T extends Throwable> T convertException(T s) {
@@ -114,8 +114,7 @@ public class PodmanCommandView extends CommandViewBase {
var sub = shellControl.subShell();
sub.setDumbOpen(createOpenFunction(container, false));
sub.setTerminalOpen(createOpenFunction(container, true));
return sub.withErrorFormatter(PodmanCommandView::formatErrorMessage)
.withExceptionConverter(PodmanCommandView::convertException);
return sub.withExceptionConverter(PodmanCommandView::convertException);
}
private ShellOpenFunction createOpenFunction(String containerName, boolean terminal) {
+2
View File
@@ -1590,3 +1590,5 @@ manageSubscription=Administrer abonnement
noListeningSshServer=Ingen lyttende SSH-server
networkScanResults=Scanningsresultater
networkScanResultsDescription=Listen over fundne systemer i netværket
localShellDialect=Lokal shell
localShellDialectDescription=Den shell, der bruges til lokale operationer. Hvis den normale lokale standard-shell er deaktiveret eller ødelagt i en eller anden grad, kan denne mulighed bruges til at falde tilbage på et andet alternativ.\n\nNogle konfigurationer som f.eks. brugerdefinerede PATH-poster gælder muligvis ikke for fallback-shellen, hvis de endnu ikke er konfigureret i de respektive shell-profilfiler.
+2
View File
@@ -1580,3 +1580,5 @@ manageSubscription=Abonnement verwalten
noListeningSshServer=Kein lauschender SSH-Server
networkScanResults=Scan-Ergebnisse
networkScanResultsDescription=Die Liste der gefundenen Systeme im Netzwerk
localShellDialect=Lokale Shell
localShellDialectDescription=Die Shell, die für lokale Operationen verwendet wird. Falls die normale lokale Standard-Shell deaktiviert oder in gewissem Maße beschädigt ist, kann mit dieser Option auf eine andere Alternative zurückgegriffen werden.\n\nEinige Konfigurationen, wie z. B. benutzerdefinierte PATH-Einträge, gelten möglicherweise nicht für die Fallback-Shell, wenn sie noch nicht in den entsprechenden Shell-Profildateien konfiguriert sind.
+2
View File
@@ -1621,3 +1621,5 @@ manageSubscription=Manage subscription
noListeningSshServer=No listening SSH server
networkScanResults=Scan results
networkScanResultsDescription=The list of found systems in the network
localShellDialect=Local shell
localShellDialectDescription=The shell that is used for local operations. In case the normal local default shell is disabled or broken to some degree, this option can be used to fall back to another alternative.\n\nSome configurations like custom PATH entries might not apply with the fallback shell if they are not configured in the respective shell profile files yet.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=Gestionar suscripción
noListeningSshServer=Ningún servidor SSH a la escucha
networkScanResults=Resultados de la exploración
networkScanResultsDescription=La lista de sistemas encontrados en la red
localShellDialect=Shell local
localShellDialectDescription=El shell que se utiliza para las operaciones locales. En caso de que el shell local normal por defecto esté desactivado o roto en algún grado, esta opción puede utilizarse para recurrir a otra alternativa.\n\nEs posible que algunas configuraciones, como las entradas PATH personalizadas, no se apliquen con el intérprete de comandos alternativo si aún no están configuradas en los respectivos archivos de perfil del intérprete de comandos.
+2
View File
@@ -1589,3 +1589,5 @@ manageSubscription=Gérer l'abonnement
noListeningSshServer=Pas de serveur SSH à l'écoute
networkScanResults=Résultats de l'analyse
networkScanResultsDescription=La liste des systèmes trouvés dans le réseau
localShellDialect=Shell local
localShellDialectDescription=L'interprète de commandes utilisé pour les opérations locales. Si l'interpréteur de commandes local par défaut normal est désactivé ou cassé dans une certaine mesure, cette option peut être utilisée pour se rabattre sur une autre alternative.\n\nCertaines configurations, comme les entrées PATH personnalisées, peuvent ne pas s'appliquer à l'interpréteur de commandes de repli si elles ne sont pas encore configurées dans les fichiers de profil de l'interpréteur de commandes respectifs.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=Mengelola langganan
noListeningSshServer=Tidak ada server SSH yang mendengarkan
networkScanResults=Hasil pemindaian
networkScanResultsDescription=Daftar sistem yang ditemukan dalam jaringan
localShellDialect=Cangkang lokal
localShellDialectDescription=Cangkang yang digunakan untuk operasi lokal. Jika shell default lokal normal dinonaktifkan atau rusak pada tingkat tertentu, opsi ini dapat digunakan untuk kembali ke alternatif lain.\n\nBeberapa konfigurasi seperti entri PATH khusus mungkin tidak berlaku dengan shell fallback jika belum dikonfigurasi dalam file profil shell yang bersangkutan.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=Gestire l'abbonamento
noListeningSshServer=Nessun server SSH in ascolto
networkScanResults=Risultati della scansione
networkScanResultsDescription=L'elenco dei sistemi trovati nella rete
localShellDialect=Guscio locale
localShellDialectDescription=La shell utilizzata per le operazioni locali. Nel caso in cui la normale shell locale predefinita sia disabilitata o in qualche modo danneggiata, questa opzione può essere utilizzata per tornare a un'altra alternativa.\n\nAlcune configurazioni come le voci PATH personalizzate potrebbero non essere applicate alla shell di ripiego se non sono ancora configurate nei rispettivi file di profilo della shell.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=サブスクリプションを管理する
noListeningSshServer=SSHサーバーをリッスンしていない
networkScanResults=スキャン結果
networkScanResultsDescription=ネットワークで見つかったシステムのリスト
localShellDialect=ローカルシェル
localShellDialectDescription=ローカル操作に使用するシェル。通常のローカルデフォルトのシェルが無効になっているか、ある程度壊れている場合、このオプションを使って別の代替シェルにフォールバックすることができる。\n\nカスタムPATHエントリーのようないくつかの設定は、それぞれのシェルプロファイルファイルでまだ設定されていない場合、フォールバックシェルでは適用されないかもしれない。
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=구독 관리
noListeningSshServer=수신 중인 SSH 서버 없음
networkScanResults=스캔 결과
networkScanResultsDescription=네트워크에서 발견된 시스템 목록
localShellDialect=로컬 셸
localShellDialectDescription=로컬 작업에 사용되는 셸입니다. 일반적인 로컬 기본 셸이 비활성화되었거나 어느 정도 고장난 경우 이 옵션을 사용하여 다른 대체 셸로 돌아갈 수 있습니다.\n\n사용자 지정 경로 항목과 같은 일부 구성은 각 셸 프로필 파일에 아직 구성되지 않은 경우 폴백 셸에 적용되지 않을 수 있습니다.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=Abonnement beheren
noListeningSshServer=Geen luisterende SSH-server
networkScanResults=Scanresultaten
networkScanResultsDescription=De lijst van gevonden systemen in het netwerk
localShellDialect=Lokale shell
localShellDialectDescription=De shell die wordt gebruikt voor lokale operaties. In het geval dat de normale lokale standaard shell is uitgeschakeld of tot op zekere hoogte kapot is, kan deze optie worden gebruikt om terug te vallen op een ander alternatief.\n\nSommige configuraties zoals aangepaste PATH entries zijn mogelijk niet van toepassing op de fallback shell als ze nog niet geconfigureerd zijn in de respectievelijke shell profielbestanden.
+2
View File
@@ -1547,3 +1547,5 @@ manageSubscription=Zarządzaj subskrypcją
noListeningSshServer=Brak nasłuchującego serwera SSH
networkScanResults=Wyniki skanowania
networkScanResultsDescription=Lista znalezionych systemów w sieci
localShellDialect=Powłoka lokalna
localShellDialectDescription=Powłoka używana do operacji lokalnych. W przypadku, gdy normalna lokalna powłoka domyślna jest wyłączona lub uszkodzona do pewnego stopnia, opcja ta może być użyta do powrotu do innej alternatywy.\n\nNiektóre konfiguracje, takie jak niestandardowe wpisy PATH, mogą nie mieć zastosowania do powłoki awaryjnej, jeśli nie zostały jeszcze skonfigurowane w odpowiednich plikach profilu powłoki.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=Gerir subscrição
noListeningSshServer=Não escuta o servidor SSH
networkScanResults=Resultados da pesquisa
networkScanResultsDescription=A lista de sistemas encontrados na rede
localShellDialect=Shell local
localShellDialectDescription=A shell que é usada para operações locais. No caso de a shell local normal por omissão estar desactivada ou avariada de alguma forma, esta opção pode ser usada para voltar a outra alternativa.\n\nAlgumas configurações como entradas PATH personalizadas podem não se aplicar com a shell de recurso se ainda não estiverem configuradas nos respectivos ficheiros de perfil da shell.
+2
View File
@@ -1660,3 +1660,5 @@ manageSubscription=Управляй подпиской
noListeningSshServer=Не прослушивается SSH-сервер
networkScanResults=Результаты сканирования
networkScanResultsDescription=Список найденных систем в сети
localShellDialect=Локальная оболочка
localShellDialectDescription=Оболочка, которая используется для локальных операций. Если обычная локальная оболочка по умолчанию отключена или в какой-то степени сломана, с помощью этой опции можно вернуться к другой альтернативе.\n\nНекоторые конфигурации, например пользовательские записи PATH, могут не применяться с резервной оболочкой, если они еще не настроены в соответствующих файлах профиля оболочки.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=Hantera prenumeration
noListeningSshServer=Ingen lyssnande SSH-server
networkScanResults=Resultat av skanning
networkScanResultsDescription=Listan över hittade system i nätverket
localShellDialect=Lokalt skal
localShellDialectDescription=Det skal som används för lokala operationer. Om det normala lokala standardskalet är inaktiverat eller trasigt i någon grad kan det här alternativet användas för att falla tillbaka på ett annat alternativ.\n\nVissa konfigurationer, t.ex. anpassade PATH-poster, kanske inte gäller för reservskalet om de inte har konfigurerats i respektive skalprofilfil ännu.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=Aboneliği yönet
noListeningSshServer=Dinleyen SSH sunucusu yok
networkScanResults=Tarama sonuçları
networkScanResultsDescription=Ağda bulunan sistemlerin listesi
localShellDialect=Yerel kabuk
localShellDialectDescription=Yerel işlemler için kullanılan kabuk. Normal yerel varsayılan kabuğun devre dışı bırakılması veya bir dereceye kadar bozulması durumunda, bu seçenek başka bir alternatife geri dönmek için kullanılabilir.\n\nÖzel PATH girişleri gibi bazı yapılandırmalar, ilgili kabuk profil dosyalarında henüz yapılandırılmamışsa, yedek kabukta uygulanmayabilir.
+2
View File
@@ -1546,3 +1546,5 @@ manageSubscription=Quản lý đăng ký
noListeningSshServer=Máy chủ SSH không nghe
networkScanResults=Kết quả quét
networkScanResultsDescription=Danh sách các hệ thống được tìm thấy trong mạng
localShellDialect=Vỏ lệnh cục bộ
localShellDialectDescription=Vỏ lệnh được sử dụng cho các thao tác cục bộ. Trong trường hợp vỏ lệnh cục bộ mặc định bị vô hiệu hóa hoặc hỏng một phần, tùy chọn này có thể được sử dụng để chuyển sang một vỏ lệnh thay thế khác.\n\nMột số cấu hình như các mục PATH tùy chỉnh có thể không áp dụng với vỏ lệnh thay thế nếu chúng chưa được cấu hình trong các tệp cấu hình vỏ lệnh tương ứng.
+2
View File
@@ -1766,3 +1766,5 @@ manageSubscription=管理订阅
noListeningSshServer=无监听 SSH 服务器
networkScanResults=扫描结果
networkScanResultsDescription=网络中找到的系统列表
localShellDialect=本地 shell
localShellDialectDescription=用于本地操作的 shell。如果正常的本地默认 shell 在某种程度上被禁用或损坏,则可使用此选项返回到另一种选择。\n\n某些配置(如自定义 PATH 条目)如果尚未在相应的 shell 配置文件中配置,则可能不适用于备用 shell。