Author Archives: Robins

[Solved] must appear in the GROUP BY clause or be used in an aggregate function

Today, when I use Postgres database to write sql, I found an error after execution: column “XXXXXX” must appear in the GROUP BY clause or be used in an aggregate function. After putting the query fields into groups according to the prompts, the results of the query are not what I need. Yes, I checked the solution on the Internet, hereby record

The cause of the problem: This is a common aggregation problem in pgsql. Before the SQL3 standard, the field selected for display must appear in  GROUP BY the

Assuming that there is a makerar table, the data is as follows:

 cname  | wmname |          avg           
--------+-------------+------------------------
 canada | zoro   |     2.0000000000000000
 spain  | luffy  | 1.00000000000000000000
 spain  | usopp  |     5.0000000000000000

I would like tocname grouping query to avg value of the largest data, sql as follows

SELECT cname, wmname, MAX(avg)  FROM makerar GROUP BY cname;

However, error

ERROR:  column "makerar.wmname" must appear in the GROUP BY clause or be used in an   aggregate function 
LINE 1: SELECT cname, wmname, MAX(avg)  FROM makerar GROUP BY cname;

So, I putAfter the group that wmname joined

SELECT cname, wmname, MAX(avg)  FROM makerar GROUP BY cname, wmname;

The result is as follows, but this is not the data I want

cname  | wmname |          max           
--------+--------+------------------------
 canada | zoro   |     2.0000000000000000
 spain  | luffy  | 1.00000000000000000000
 spain  | usopp  |     5.0000000000000000

My desired data result is

 cname  | wmname |          max           
--------+--------+------------------------
 canada | zoro   |     2.0000000000000000
 spain  | usopp  |     5.0000000000000000

There are two ways to solve this problem:

1. Using nested sql, compute the aggregate in a subquery, then join it with itself to get the additional columns that need to be displayed

SELECT m.cname, m.wmname, t.mx
FROM (
    SELECT cname, MAX(avg) AS mx
    FROM makerar
    GROUP BY cname
    ) t JOIN makerar m ON m.cname = t.cname AND t.mx = m.avg
;

 cname  | wmname |          mx           
--------+--------+------------------------
 canada | zoro   |     2.0000000000000000
 spain  | usopp  |     5.0000000000000000

2. Use the special DISTINCT ON expression

SELECT DISTINCT ON (cname) 
    cname, wmname, avg
FROM 
    makerar
ORDER BY 
    cname, avg DESC ;

Combined with your own business, use the first method to transform sql

    SELECT
        pihs.pat_status,
        b.bed_class_id,
        pih.charge_class_id,
        pihs.pat_condition,
        pih.pat_id,
        pihs.room_with_mother_baby_flag,
        pc.pat_in_charge_doc_name,
        pc.pat_in_charge_doc_id,
        b.bed_show_no,
        pih.pat_age AS age,
        pih.pat_in_hos_id,
        pih.pat_in_hos_code,
        pihs.pat_in_status,
        pc.state_of_critical_value,
        pih.pat_in_time,
        pc.chief_doc_id,
        pc.chief_doc_name,
        pc.dur_nurse_id,
        pc.dur_nurse_name,
        pc.first_ann_bed_time,
        pc.manage_bed_nurse_name,
        pih.pat_type_id,
        pc.pat_clinic_id,
        pc.pat_ward_id,
        b.bed_id,
        b.bed_status,
        b.is_share,
        pc.nursing_class,
        pc.nursing_class_name,
        pihs.pat_in_bed_share_status,
        pih.seven_days_again_in_flag,
        b.price,
        T.change_in_time
        FROM
        bed b
        LEFT JOIN pat_in_hospital_status pihs ON b.bed_id = pihs.bed_id
        LEFT JOIN pat_in_hospital pih ON b.pat_in_hos_id = pih.pat_in_hos_id
        LEFT JOIN pat_clinican pc ON pih.pat_in_hos_id = pc.pat_in_hos_id
        LEFT JOIN ( SELECT pat_in_hos_id, MAX ( pat_in_out_ward_time ) AS change_in_time FROM change_ward_record WHERE complete_flag = '1' GROUP BY pat_in_hos_id ) T ON pih.pat_in_hos_id = T.pat_in_hos_id
        where b.ward_id='1234'

Reference link:

https://stackoverflow.com/questions/19601948/must-appear-in-the-group-by-clause-or-be-used-in-an-aggregate-function#

[Solved] Shell Error: syntax error: invalid arithmetic operator (error token is “

When processing windows format text, use \r\n as the newline character, if the data involved in the operation is at the end of the line

syntax error: invalid arithmetic operator (error token is “

https://stackoverflow.com/questions/43309793/remove-rn-in-awk

awk -v RS= ' \r\n ' ...

 

awk  ' { sub("\r$", ""); ...}
awk  ' {sub(/\r/,"",$NF); ...} '
awk  ' BEGIN { RS=ORS="\r\n"; ...

 

foo=$ ' 5\r ' ; echo $(( 5 + foo))

" )syntax error: invalid arithmetic operator (error token is "

 

foo=$ ' 5\r ' ; echo $(( 5 +${foo // $'\r'}))

 

foo=$ ' 5\r ' ; echo $(( 5 +$( tr -d ' \r ' <<< " $foo " )))

 

or remove \r

foo=$ ' 5\r ' ; foo=${foo // $'\r'}

[Solved] FATAL ERROR: wasm code commit Allocation failed – process out of memory

Phenomenon:

Computer model: Apple M1

When starting the vite project, the terminal reports:

FATAL ERROR: wasm code commit Allocation failed - process out of memory
 1: 0x10283d758 node::Abort() [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
 2: 0x10283d8bc node::OnFatalError(char const*, char const*) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
 3: 0x10295d6a8 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
 4: 0x10295d63c v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
 5: 0x102e9cb1c v8::internal::wasm::WasmCodeAllocator::AllocateForCodeInRegion(v8::internal::wasm::NativeModule*, unsigned long, v8::base::AddressRegion) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
 6: 0x102e9d948 v8::internal::wasm::NativeModule::CreateEmptyJumpTableInRegion(unsigned int, v8::base::AddressRegion) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
 7: 0x102e9ce10 v8::internal::wasm::NativeModule::AddCodeSpace(v8::base::AddressRegion) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
 8: 0x102e9d784 v8::internal::wasm::NativeModule::NativeModule(v8::internal::wasm::WasmEngine*, v8::internal::wasm::WasmFeatures const&, bool, v8::internal::VirtualMemory, std::__1::shared_ptr<v8::internal::wasm::WasmModule const>, std::__1::shared_ptr<v8::internal::Counters>, std::__1::shared_ptr<v8::internal::wasm::NativeModule>*) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
 9: 0x102e9f9f4 v8::internal::wasm::WasmCodeManager::NewNativeModule(v8::internal::wasm::WasmEngine*, v8::internal::Isolate*, v8::internal::wasm::WasmFeatures const&, unsigned long, bool, std::__1::shared_ptr<v8::internal::wasm::WasmModule const>) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
10: 0x102ea60c4 v8::internal::wasm::WasmEngine::NewNativeModule(v8::internal::Isolate*, v8::internal::wasm::WasmFeatures const&, unsigned long, bool, std::__1::shared_ptr<v8::internal::wasm::WasmModule const>) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
11: 0x102ea6004 v8::internal::wasm::WasmEngine::NewNativeModule(v8::internal::Isolate*, v8::internal::wasm::WasmFeatures const&, std::__1::shared_ptr<v8::internal::wasm::WasmModule const>) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
12: 0x102e7e85c v8::internal::wasm::AsyncCompileJob::CreateNativeModule(std::__1::shared_ptr<v8::internal::wasm::WasmModule const>) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
13: 0x102e87750 v8::internal::wasm::AsyncCompileJob::PrepareAndStartCompile::RunInForeground(v8::internal::wasm::AsyncCompileJob*) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
14: 0x102e87fd8 v8::internal::wasm::AsyncCompileJob::CompileTask::RunInternal() [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
15: 0x10289d1e8 node::PerIsolatePlatformData::RunForegroundTask(std::__1::unique_ptr<v8::Task, std::__1::default_delete<v8::Task> >) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
16: 0x10289c29c node::PerIsolatePlatformData::FlushForegroundTasksInternal() [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
17: 0x102ffcd5c uv__async_io [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
18: 0x10300e714 uv__io_poll [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
19: 0x102ffd1ec uv_run [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
20: 0x102878e94 node::NodeMainInstance::Run() [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
21: 0x102817b54 node::Start(int, char**) [/Users/yangyanhui/.nvm/versions/node/v12.22.10/bin/node]
solution:
➜ ✗ nvm uninstall v12.22.10
➜ ✗ arch -x86_64 zsh
➜ ✗ nvm install v12.22.10

[Solved] Mac Error: ERROR launching ‘JD-GUI’

Solution: Display the package contents of the app, find universalJavaApplicationStub.sh and copy the following to overwrite it

#!/bin/bash
##################################################################################
#                                                                                #
# universalJavaApplicationStub                                                   #
#                                                                                #
# A BASH based JavaApplicationStub for Java Apps on Mac OS X                     #
# that works with both Apple's and Oracle's plist format.                        #
#                                                                                #
# Inspired by Ian Roberts stackoverflow answer                                   #
# at http://stackoverflow.com/a/17546508/1128689                                 #
#                                                                                #
# @author    Tobias Fischer                                                      #
# @url       https://github.com/tofi86/universalJavaApplicationStub              #
# @date      2020-03-19                                                          #
# @version   3.0.6                                                               #
#                                                                                #
##################################################################################
#                                                                                #
# The MIT License (MIT)                                                          #
#                                                                                #
# Copyright (c) 2014-2020 Tobias Fischer                                         #
#                                                                                #
# Permission is hereby granted, free of charge, to any person obtaining a copy   #
# of this software and associated documentation files (the "Software"), to deal  #
# in the Software without restriction, including without limitation the rights   #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell      #
# copies of the Software, and to permit persons to whom the Software is          #
# furnished to do so, subject to the following conditions:                       #
#                                                                                #
# The above copyright notice and this permission notice shall be included in all #
# copies or substantial portions of the Software.                                #
#                                                                                #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR     #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,       #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE    #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  #
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  #
# SOFTWARE.                                                                      #
#                                                                                #
##################################################################################
 
 
 
# function 'stub_logger()'
#
# A logger which logs to the macOS Console.app using the 'syslog' command
#
# @param1  the log message
# @return  void
################################################################################
function stub_logger() {
	syslog -s -k \
		Facility com.apple.console \
		Level Notice \
		Sender "$(basename "$0")" \
		Message "[$$][${CFBundleName:-$(basename "$0")}] $1"
}
 
 
 
# set the directory abspath of the current
# shell script with symlinks being resolved
############################################
 
PRG=$0
while [ -h "$PRG" ]; do
	ls=$(ls -ld "$PRG")
	link=$(expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null)
	if expr "$link" : '^/' 2> /dev/null >/dev/null; then
		PRG="$link"
	else
		PRG="$(dirname "$PRG")/$link"
	fi
done
PROGDIR=$(dirname "$PRG")
stub_logger "[StubDir] $PROGDIR"
 
 
 
# set files and folders
############################################
 
# the absolute path of the app package
cd "$PROGDIR"/../../ || exit 11
AppPackageFolder=$(pwd)
 
# the base path of the app package
cd .. || exit 12
AppPackageRoot=$(pwd)
 
# set Apple's Java folder
AppleJavaFolder="${AppPackageFolder}"/Contents/Resources/Java
 
# set Apple's Resources folder
AppleResourcesFolder="${AppPackageFolder}"/Contents/Resources
 
# set Oracle's Java folder
OracleJavaFolder="${AppPackageFolder}"/Contents/Java
 
# set Oracle's Resources folder
OracleResourcesFolder="${AppPackageFolder}"/Contents/Resources
 
# set path to Info.plist in bundle
InfoPlistFile="${AppPackageFolder}"/Contents/Info.plist
 
# set the default JVM Version to a null string
JVMVersion=""
JVMMaxVersion=""
 
 
 
# function 'plist_get()'
#
# read a specific Plist key with 'PlistBuddy' utility
#
# @param1  the Plist key with leading colon ':'
# @return  the value as String or Array
################################################################################
plist_get(){
	/usr/libexec/PlistBuddy -c "print $1" "${InfoPlistFile}" 2> /dev/null
}
 
# function 'plist_get_java()'
#
# read a specific Plist key with 'PlistBuddy' utility
# in the 'Java' or 'JavaX' dictionary ()
#
# @param1  the Plist :Java(X):Key with leading colon ':'
# @return  the value as String or Array
################################################################################
plist_get_java(){
	plist_get ${JavaKey:-":Java"}$1
}
 
 
 
# read Info.plist and extract JVM options
############################################
 
# read the program name from CFBundleName
CFBundleName=$(plist_get ':CFBundleName')
 
# read the icon file name
CFBundleIconFile=$(plist_get ':CFBundleIconFile')
 
 
# check Info.plist for Apple style Java keys -> if key :Java is present, parse in apple mode
/usr/libexec/PlistBuddy -c "print :Java" "${InfoPlistFile}" > /dev/null 2>&1
exitcode=$?
JavaKey=":Java"
 
# if no :Java key is present, check Info.plist for universalJavaApplication style JavaX keys -> if key :JavaX is present, parse in apple mode
if [ $exitcode -ne 0 ]; then
	/usr/libexec/PlistBuddy -c "print :JavaX" "${InfoPlistFile}" > /dev/null 2>&1
	exitcode=$?
	JavaKey=":JavaX"
fi
 
 
# read 'Info.plist' file in Apple style if exit code returns 0 (true, ':Java' key is present)
if [ $exitcode -eq 0 ]; then
	stub_logger "[PlistStyle] Apple"
 
	# set Java and Resources folder
	JavaFolder="${AppleJavaFolder}"
	ResourcesFolder="${AppleResourcesFolder}"
 
	APP_PACKAGE="${AppPackageFolder}"
	JAVAROOT="${AppleJavaFolder}"
	USER_HOME="$HOME"
 
 
	# read the Java WorkingDirectory
	JVMWorkDir=$(plist_get_java ':WorkingDirectory' | xargs)
	# set Working Directory based upon PList value
	if [[ ! -z ${JVMWorkDir} ]]; then
		WorkingDirectory="${JVMWorkDir}"
	else
		# AppPackageRoot is the standard WorkingDirectory when the script is started
		WorkingDirectory="${AppPackageRoot}"
	fi
	# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
	WorkingDirectory=$(eval echo "${WorkingDirectory}")
 
 
	# read the MainClass name
	JVMMainClass="$(plist_get_java ':MainClass')"
 
	# read the SplashFile name
	JVMSplashFile=$(plist_get_java ':SplashFile')
 
	# read the JVM Properties as an array and retain spaces
	IFS=$'\t\n'
	JVMOptions=($(xargs -n1 <<<$(plist_get_java ':Properties' | grep " =" | sed 's/^ */-D/g' | sed -E 's/ = (.*)$/="\1"/g')))
	unset IFS
	# post processing of the array follows further below...
 
	# read the ClassPath in either Array or String style
	JVMClassPath_RAW=$(plist_get_java ':ClassPath' | xargs)
	if [[ $JVMClassPath_RAW == *Array* ]] ; then
		JVMClassPath=.$(plist_get_java ':ClassPath' | grep "    " | sed 's/^ */:/g' | tr -d '\n' | xargs)
	else
		JVMClassPath=${JVMClassPath_RAW}
	fi
	# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
	JVMClassPath=$(eval echo "${JVMClassPath}")
 
	# read the JVM Options in either Array or String style
	JVMDefaultOptions_RAW=$(plist_get_java ':VMOptions' | xargs)
	if [[ $JVMDefaultOptions_RAW == *Array* ]] ; then
		JVMDefaultOptions=$(plist_get_java ':VMOptions' | grep "    " | sed 's/^ */ /g' | tr -d '\n' | xargs)
	else
		JVMDefaultOptions=${JVMDefaultOptions_RAW}
	fi
 
	# read StartOnMainThread and add as -XstartOnFirstThread
	JVMStartOnMainThread=$(plist_get_java ':StartOnMainThread')
	if [ "${JVMStartOnMainThread}" == "true" ]; then
		JVMDefaultOptions+=" -XstartOnFirstThread"
	fi
 
	# read the JVM Arguments in either Array or String style (#76) and retain spaces
	IFS=$'\t\n'
	MainArgs_RAW=$(plist_get_java ':Arguments' | xargs)
	if [[ $MainArgs_RAW == *Array* ]] ; then
		MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/  */ /g')))
	else
		MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
	fi
	unset IFS
	# post processing of the array follows further below...
 
	# read the Java version we want to find
	JVMVersion=$(plist_get_java ':JVMVersion' | xargs)
	# post processing of the version string follows below...
 
 
# read 'Info.plist' file in Oracle style
else
	stub_logger "[PlistStyle] Oracle"
 
	# set Working Directory and Java and Resources folder
	JavaFolder="${OracleJavaFolder}"
	ResourcesFolder="${OracleResourcesFolder}"
	WorkingDirectory="${OracleJavaFolder}"
 
	APP_ROOT="${AppPackageFolder}"
 
	# read the MainClass name
	JVMMainClass="$(plist_get ':JVMMainClassName')"
 
	# read the SplashFile name
	JVMSplashFile=$(plist_get ':JVMSplashFile')
 
	# read the JVM Options as an array and retain spaces
	IFS=$'\t\n'
	JVMOptions=($(plist_get ':JVMOptions' | grep "    " | sed 's/^ *//g'))
	unset IFS
	# post processing of the array follows further below...
 
	# read the ClassPath in either Array or String style
	JVMClassPath_RAW=$(plist_get ':JVMClassPath')
	if [[ $JVMClassPath_RAW == *Array* ]] ; then
		JVMClassPath=.$(plist_get ':JVMClassPath' | grep "    " | sed 's/^ */:/g' | tr -d '\n' | xargs)
		# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
		JVMClassPath=$(eval echo "${JVMClassPath}")
 
	elif [[ ! -z ${JVMClassPath_RAW} ]] ; then
		JVMClassPath=${JVMClassPath_RAW}
		# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
		JVMClassPath=$(eval echo "${JVMClassPath}")
 
	else
		#default: fallback to OracleJavaFolder
		JVMClassPath="${JavaFolder}/*"
		# Do NOT expand the default 'AppName.app/Contents/Java/*' classpath (#42)
	fi
 
	# read the JVM Default Options
	JVMDefaultOptions=$(plist_get ':JVMDefaultOptions' | grep -o " \-.*" | tr -d '\n' | xargs)
 
	# read the Main Arguments from JVMArguments key as an array and retain spaces (see #46 for naming details)
	IFS=$'\t\n'
	MainArgs=($(xargs -n1 <<<$(plist_get ':JVMArguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/ */ /g'))) unset IFS # post processing of the array follows further below... # read the Java version we want to find JVMVersion=$(plist_get ':JVMVersion' | xargs) # post processing of the version string follows below... fi # (#75) check for undefined icons or icon names without .icns extension and prepare # an osascript statement for those cases when the icon can be shown in the dialog DialogWithIcon="" if [ ! -z ${CFBundleIconFile} ]; then if [[ ${CFBundleIconFile} == *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}" ]] ; then DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" elif [[ ${CFBundleIconFile} != *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}.icns" ]] ; then CFBundleIconFile+=".icns" DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" fi fi # JVMVersion: post processing and optional splitting if [[ ${JVMVersion} == *";"* ]]; then minMaxArray=(${JVMVersion//;/ }) JVMVersion=${minMaxArray[0]//+} JVMMaxVersion=${minMaxArray[1]//+} fi stub_logger "[JavaRequirement] JVM minimum version: ${JVMVersion}" stub_logger "[JavaRequirement] JVM maximum version: ${JVMMaxVersion}" # MainArgs: replace occurences of $APP_ROOT with its content MainArgsArr=() for i in "${MainArgs[@]}" do MainArgsArr+=("$(eval echo "$i")") done # JVMOptions: replace occurences of $APP_ROOT with its content JVMOptionsArr=() for i in "${JVMOptions[@]}" do JVMOptionsArr+=("$(eval echo "$i")") done # internationalized messages ############################################ LANG=$(defaults read -g AppleLocale) stub_logger "[Language] $LANG" # French localization if [[ $LANG == fr* ]] ; then MSG_ERROR_LAUNCHING="ERREUR au lancement de '${CFBundleName}'." MSG_MISSING_MAINCLASS="'MainClass' n'est pas spécifié.\nL'application Java ne peut pas être lancée." MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application." MSG_NO_SUITABLE_JAVA="La version de Java installée sur votre système ne convient pas.\nCe programme nécessite Java %s" MSG_JAVA_VERSION_OR_LATER="ou ultérieur" MSG_JAVA_VERSION_LATEST="(dernière mise à jour)" MSG_JAVA_VERSION_MAX="à %s" MSG_NO_SUITABLE_JAVA_CHECK="Merci de bien vouloir installer la version de Java requise." MSG_INSTALL_JAVA="Java doit être installé sur votre système.\nRendez-vous sur java.com et suivez les instructions d'installation..." MSG_LATER="Plus tard" MSG_VISIT_JAVA_DOT_COM="Java by Oracle" MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK" # German localization elif [[ $LANG == de* ]] ; then MSG_ERROR_LAUNCHING="FEHLER beim Starten von '${CFBundleName}'." MSG_MISSING_MAINCLASS="Die 'MainClass' ist nicht spezifiziert!\nDie Java-Anwendung kann nicht gestartet werden!" MSG_JVMVERSION_REQ_INVALID="Die Syntax der angeforderten Java-Version ist ungültig: %s\nBitte kontaktieren Sie den Entwickler der App." MSG_NO_SUITABLE_JAVA="Es wurde keine passende Java-Version auf Ihrem System gefunden!\nDieses Programm benötigt Java %s" MSG_JAVA_VERSION_OR_LATER="oder neuer" MSG_JAVA_VERSION_LATEST="(neuste Unterversion)" MSG_JAVA_VERSION_MAX="bis %s" MSG_NO_SUITABLE_JAVA_CHECK="Stellen Sie sicher, dass die angeforderte Java-Version installiert ist." MSG_INSTALL_JAVA="Auf Ihrem System muss die 'Java'-Software installiert sein.\nBesuchen Sie java.com für weitere Installationshinweise." MSG_LATER="Später" MSG_VISIT_JAVA_DOT_COM="Java von Oracle" MSG_VISIT_ADOPTOPENJDK="Java von AdoptOpenJDK" # Simplifyed Chinese localization elif [[ $LANG == zh* ]] ; then MSG_ERROR_LAUNCHING="Unable to start '${CFBundleName}'." MSG_MISSING_MAINCLASS="No 'MainClass' specified! \nJava program could not be started!" MSG_JVMVERSION_REQ_INVALID="Java version parameter syntax error: %s\nPlease contact the developer of this application." MSG_NO_SUITABLE_JAVA="No suitable version of Java found on the system! \nJava %s must be installed to be able to use this application!" MSG_JAVA_VERSION_OR_LATER="and above" MSG_JAVA_VERSION_LATEST="(latest version)" MSG_JAVA_VERSION_MAX="up to %s" MSG_NO_SUITABLE_JAVA_CHECK="Please ensure that the required version of Java is installed on your system" MSG_INSTALL_JAVA="You need to install the Java runtime environment on your Mac! \nVisit java.com to learn how to install it." MSG_LATER="Later" MSG_VISIT_JAVA_DOT_COM="Java by Oracle" MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK" # English default localization else MSG_ERROR_LAUNCHING="ERROR launching '${CFBundleName}'." MSG_MISSING_MAINCLASS="'MainClass' isn't specified!\nJava application cannot be started!" MSG_JVMVERSION_REQ_INVALID="The syntax of the required Java version is invalid: %s\nPlease contact the App developer." MSG_NO_SUITABLE_JAVA="No suitable Java version found on your system!\nThis program requires Java %s" MSG_JAVA_VERSION_OR_LATER="or later" MSG_JAVA_VERSION_LATEST="(latest update)" MSG_JAVA_VERSION_MAX="up to %s" MSG_NO_SUITABLE_JAVA_CHECK="Make sure you install the required Java version." MSG_INSTALL_JAVA="You need to have JAVA installed on your Mac!\nVisit java.com for installation instructions..." MSG_LATER="Later" MSG_VISIT_JAVA_DOT_COM="Java by Oracle" MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK" fi # function 'get_java_version_from_cmd()' # # returns Java version string from 'java -version' command # works for both old (1.8) and new (9) version schema # # @param1 path to a java JVM executable # @return the Java version number as displayed in 'java -version' command ################################################################################ function get_java_version_from_cmd() { # second sed command strips " and -ea from the version string echo $("$1" -version 2>&1 | awk '/version/{print $3}' | sed -E 's/"//g;s/-ea//g')
}
 
 
# function 'extract_java_major_version()'
#
# extract Java major version from a version string
#
# @param1  a Java version number ('1.8.0_45') or requirement string ('1.8+')
# @return  the major version (e.g. '7', '8' or '9', etc.)
################################################################################
function extract_java_major_version() {
	echo $(echo "$1" | sed -E 's/^1\.//;s/^([0-9]+)(-ea|(\.[0-9_.]{1,7})?)(-b[0-9]+-[0-9]+)?[+*]?$/\1/')
}
 
 
# function 'get_comparable_java_version()'
#
# return comparable version for a Java version number or requirement string
#
# @param1  a Java version number ('1.8.0_45') or requirement string ('1.8+')
# @return  an 8 digit numeral ('1.8.0_45'->'08000045'; '9.1.13'->'09001013')
################################################################################
function get_comparable_java_version() {
	# cleaning: 1) remove leading '1.'; 2) remove build string (e.g. '-b14-468'); 3) remove 'a-Z' and '-*+' (e.g. '-ea'); 4) replace '_' with '.'
	local cleaned=$(echo "$1" | sed -E 's/^1\.//g;s/-b[0-9]+-[0-9]+$//g;s/[a-zA-Z+*\-]//g;s/_/./g')
	# splitting at '.' into an array
	local arr=( ${cleaned//./ } )
	# echo a string with left padded version numbers
	echo "$(printf '%02s' ${arr[0]})$(printf '%03s' ${arr[1]})$(printf '%03s' ${arr[2]})"
}
 
 
# function 'is_valid_requirement_pattern()'
#
# check whether the Java requirement is a valid requirement pattern
#
# supported requirements are for example:
# - 1.6       requires Java 6 (any update)      [1.6, 1.6.0_45, 1.6.0_88]
# - 1.6*      requires Java 6 (any update)      [1.6, 1.6.0_45, 1.6.0_88]
# - 1.6+      requires Java 6 or higher         [1.6, 1.6.0_45, 1.8, 9, etc.]
# - 1.6.0     requires Java 6 (any update)      [1.6, 1.6.0_45, 1.6.0_88]
# - 1.6.0_45  requires Java 6u45                [1.6.0_45]
# - 1.6.0_45+ requires Java 6u45 or higher      [1.6.0_45, 1.6.0_88, 1.8, etc.]
# - 9         requires Java 9 (any update)      [9.0.*, 9.1, 9.3, etc.]
# - 9*        requires Java 9 (any update)      [9.0.*, 9.1, 9.3, etc.]
# - 9+        requires Java 9 or higher         [9.0, 9.1, 10, etc.]
# - 9.1       requires Java 9.1 (any update)    [9.1.*, 9.1.2, 9.1.13, etc.]
# - 9.1*      requires Java 9.1 (any update)    [9.1.*, 9.1.2, 9.1.13, etc.]
# - 9.1+      requires Java 9.1 or higher       [9.1, 9.2, 10, etc.]
# - 9.1.3     requires Java 9.1.3               [9.1.3]
# - 9.1.3*    requires Java 9.1.3 (any update)  [9.1.3]
# - 9.1.3+    requires Java 9.1.3 or higher     [9.1.3, 9.1.4, 9.2.*, 10, etc.]
# - 10-ea     requires Java 10 (early access release)
#
# unsupported requirement patterns are for example:
# - 1.2, 1.3, 1.9       Java 2, 3 are not supported
# - 1.9                 Java 9 introduced a new versioning scheme
# - 6u45                known versioning syntax, but unsupported
# - 9-ea*, 9-ea+        early access releases paired with */+
# - 9., 9.*, 9.+        version ending with a .
# - 9.1., 9.1.*, 9.1.+  version ending with a .
# - 9.3.5.6             4 part version number is unsupported
#
# @param1  a Java requirement string ('1.8+')
# @return  boolean exit code: 0 (is valid), 1 (is not valid)
################################################################################
function is_valid_requirement_pattern() {
	local java_req=$1
	java8pattern='1\.[4-8](\.[0-9]+)?(\.0_[0-9]+)?[*+]?'
	java9pattern='(9|1[0-9])(-ea|[*+]|(\.[0-9]+){1,2}[*+]?)?'
	# test matches either old Java versioning scheme (up to 1.8) or new scheme (starting with 9)
	if [[ ${java_req} =~ ^(${java8pattern}|${java9pattern})$ ]]; then
		return 0
	else
		return 1
	fi
}
 
 
 
# determine which JVM to use
############################################
 
# default Apple JRE plugin path (< 1.6) apple_jre_plugin="/Library/Java/Home/bin/java" apple_jre_version=$(get_java_version_from_cmd "${apple_jre_plugin}") # default Oracle JRE plugin path (>= 1.7)
oracle_jre_plugin="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java"
oracle_jre_version=$(get_java_version_from_cmd "${oracle_jre_plugin}")
 
 
# first check system variable "$JAVA_HOME" -> has precedence over any other System JVM
stub_logger '[JavaSearch] Checking for $JAVA_HOME ...'
if [ -n "$JAVA_HOME" ] ; then
	stub_logger "[JavaSearch] ... found JAVA_HOME with value $JAVA_HOME"
 
	# PR 26: Allow specifying "$JAVA_HOME" relative to "$AppPackageFolder"
	# which allows for bundling a custom version of Java inside your app!
	if [[ $JAVA_HOME == /* ]] ; then
		# if "$JAVA_HOME" starts with a Slash it's an absolute path
		JAVACMD="$JAVA_HOME/bin/java"
	else
		# otherwise it's a relative path to "$AppPackageFolder"
		JAVACMD="$AppPackageFolder/$JAVA_HOME/bin/java"
	fi
	JAVACMD_version=$(get_comparable_java_version $(get_java_version_from_cmd "${JAVACMD}"))
else
	stub_logger "[JavaSearch] ... didn't found JAVA_HOME"
fi
 
 
# check for any other or a specific Java version
# also if $JAVA_HOME exists but isn't executable
if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
	stub_logger "[JavaSearch] Checking for JavaVirtualMachines on the system ..."
	# reset variables
	JAVACMD=""
	JAVACMD_version=""
 
	# first check whether JVMVersion string is a valid requirement string
	if [ ! -z "${JVMVersion}" ] && ! is_valid_requirement_pattern ${JVMVersion} ; then
		MSG_JVMVERSION_REQ_INVALID_EXPANDED=$(printf "${MSG_JVMVERSION_REQ_INVALID}" "${JVMVersion}")
		# log exit cause
		stub_logger "[EXIT 4] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
		# display error message with AppleScript
		osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
		# exit with error
		exit 4
	fi
	# then check whether JVMMaxVersion string is a valid requirement string
	if [ ! -z "${JVMMaxVersion}" ] && ! is_valid_requirement_pattern ${JVMMaxVersion} ; then
		MSG_JVMVERSION_REQ_INVALID_EXPANDED=$(printf "${MSG_JVMVERSION_REQ_INVALID}" "${JVMMaxVersion}")
		# log exit cause
		stub_logger "[EXIT 5] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
		# display error message with AppleScript
		osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
		# exit with error
		exit 5
	fi
 
 
	# find installed JavaVirtualMachines (JDK + JRE)
	allJVMs=()
	# read JDK's from '/usr/libexec/java_home -V' command
	while read -r line; do
		version=$(echo $line | awk -F $',' '{print $1;}')
		path=$(echo $line | awk -F $'" ' '{print $2;}')
		path+="/bin/java"
		allJVMs+=("$version:$path")
	done < <(/usr/libexec/java_home -V 2>&1 | grep '^[[:space:]]')
	# unset while loop variables
	unset version path
 
	# add Apple JRE if available
	if [ -x "${apple_jre_plugin}" ] ; then
		allJVMs+=("$apple_jre_version:$apple_jre_plugin")
	fi
 
	# add Oracle JRE if available
	if [ -x "${oracle_jre_plugin}" ] ; then
		allJVMs+=("$oracle_jre_version:$oracle_jre_plugin")
	fi
 
	# debug output
	for i in "${allJVMs[@]}"
	do
		stub_logger "[JavaSearch] ... found JVM: $i"
	done
 
 
	# determine JVMs matching the min/max version requirement
	minC=$(get_comparable_java_version ${JVMVersion})
	maxC=$(get_comparable_java_version ${JVMMaxVersion})
	matchingJVMs=()
 
	for i in "${allJVMs[@]}"
	do
		# split JVM string at ':' delimiter to retain spaces in $path substring
		IFS=: arr=($i) ; unset IFS
		# [0] JVM version number
		ver=${arr[0]}
		# comparable JVM version number
		comp=$(get_comparable_java_version $ver)
		# [1] JVM path
		path="${arr[1]}"
		# construct string item for adding to the "matchingJVMs" array
		item="$comp:$ver:$path"
 
		# pre-requisite: current version number needs to be greater than min version number
		if [ "$comp" -ge "$minC" ] ; then
 
			# perform max version checks if max version requirement is present
			if [ ! -z ${JVMMaxVersion} ] ; then
 
				# max version requirement ends with '*' modifier
				if [[ ${JVMMaxVersion} == *\* ]] ; then
 
					# use the '*' modifier from the max version string as wildcard for a 'starts with' comparison
					# and check whether the current version number starts with the max version wildcard string
					if [[ ${ver} == ${JVMMaxVersion} ]]; then
						matchingJVMs+=("$item")
 
					# or whether the current comparable version is lower than the comparable max version
					elif [ "$comp" -le "$maxC" ] ; then
						matchingJVMs+=("$item")
					fi
 
				# max version requirement ends with '+' modifier -> always add this version if it's greater than $min
				# because a max requirement with + modifier doesn't make sense
				elif [[ ${JVMMaxVersion} == *+ ]] ; then
					matchingJVMs+=("$item")
 
				# matches 6 zeros at the end of the max version string (e.g. for 1.8, 9)
				# -> then the max version string should be treated like with a '*' modifier at the end
				#elif [[ ${maxC} =~ ^[0-9]{2}0{6}$ ]] && [ "$comp" -le $(( ${maxC#0} + 999 )) ] ; then
				#	matchingJVMs+=("$item")
 
				# matches 3 zeros at the end of the max version string (e.g. for 9.1, 10.3)
				# -> then the max version string should be treated like with a '*' modifier at the end
				#elif [[ ${maxC} =~ ^[0-9]{5}0{3}$ ]] && [ "$comp" -le "${maxC}" ] ; then
				#	matchingJVMs+=("$item")
 
				# matches standard requirements without modifier
				elif [ "$comp" -le "$maxC" ]; then
					matchingJVMs+=("$item")
				fi
 
			# no max version requirement:
 
			# min version requirement ends with '+' modifier
			# -> always add the current version because it's greater than $min
			elif [[ ${JVMVersion} == *+ ]] ; then
				matchingJVMs+=("$item")
 
			# min version requirement ends with '*' modifier
			# -> use the '*' modifier from the min version string as wildcard for a 'starts with' comparison
			#    and check whether the current version number starts with the min version wildcard string
			elif [[ ${JVMVersion} == *\* ]] ; then
				if [[ ${ver} == ${JVMVersion} ]] ; then
					matchingJVMs+=("$item")
				fi
 
			# compare the min version against the current version with an additional * wildcard for a 'starts with' comparison
			# -> e.g. add 1.8.0_44 when the requirement is 1.8
			elif [[ ${ver} == ${JVMVersion}* ]] ; then
					matchingJVMs+=("$item")
			fi
		fi
	done
	# unset for loop variables
	unset arr ver comp path item
 
	# debug output
	for i in "${matchingJVMs[@]}"
	do
		stub_logger "[JavaSearch] ... ... matches all requirements: $i"
	done
 
 
	# sort the matching JavaVirtualMachines by version number
	# https://stackoverflow.com/a/11789688/1128689
	IFS=$'\n' matchingJVMs=($(sort -nr <<<"${matchingJVMs[*]}"))
	unset IFS
 
 
	# get the highest matching JVM
	for ((i = 0; i < ${#matchingJVMs[@]}; i++));
	do
		# split JVM string at ':' delimiter to retain spaces in $path substring
		IFS=: arr=(${matchingJVMs[$i]}) ; unset IFS
		# [0] comparable JVM version number
		comp=${arr[0]}
		# [1] JVM version number
		ver=${arr[1]}
		# [2] JVM path
		path="${arr[2]}"
 
		# use current value as JAVACMD if it's executable
		if [ -x "$path" ] ; then
			JAVACMD="$path"
			JAVACMD_version=$comp
			break
		fi
	done
	# unset for loop variables
	unset arr comp ver path
fi
 
# log the Java Command and the extracted version number
stub_logger "[JavaCommand] '$JAVACMD'"
stub_logger "[JavaVersion] $(get_java_version_from_cmd "${JAVACMD}")${JAVACMD_version:+ / $JAVACMD_version}"
 
 
 
if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
	# different error messages when a specific JVM was required
	if [ ! -z "${JVMVersion}" ] ; then
		# display human readable java version (#28)
		java_version_hr=$(echo ${JVMVersion} | sed -E 's/^1\.([0-9+*]+)$/ \1/g' | sed "s/+/ ${MSG_JAVA_VERSION_OR_LATER}/;s/*/ ${MSG_JAVA_VERSION_LATEST}/")
		MSG_NO_SUITABLE_JAVA_EXPANDED=$(printf "${MSG_NO_SUITABLE_JAVA}" "${java_version_hr}").
 
		if [ ! -z "${JVMMaxVersion}" ] ; then
			java_version_hr=$(extract_java_major_version ${JVMVersion})
			java_version_max_hr=$(echo ${JVMMaxVersion} | sed -E 's/^1\.([0-9+*]+)$/ \1/g' | sed "s/+//;s/*/ ${MSG_JAVA_VERSION_LATEST}/")
			MSG_NO_SUITABLE_JAVA_EXPANDED="$(printf "${MSG_NO_SUITABLE_JAVA}" "${java_version_hr}") $(printf "${MSG_JAVA_VERSION_MAX}" "${java_version_max_hr}")"
		fi
 
		# log exit cause
		stub_logger "[EXIT 3] ${MSG_NO_SUITABLE_JAVA_EXPANDED}"
 
		# display error message with AppleScript
		osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\"  buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
				-e "set response to button returned of the result" \
				-e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
				-e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
		# exit with error
		exit 3
 
	else
		# log exit cause
		stub_logger "[EXIT 1] ${MSG_ERROR_LAUNCHING}"
		# display error message with AppleScript
		osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_INSTALL_JAVA}\" with title \"${CFBundleName}\" buttons {\"${MSG_LATER}\", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
					-e "set response to button returned of the result" \
					-e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
					-e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
		# exit with error
		exit 1
	fi
fi
 
 
 
# MainClass check
############################################
 
if [ -z "${JVMMainClass}" ]; then
	# log exit cause
	stub_logger "[EXIT 2] ${MSG_MISSING_MAINCLASS}"
	# display error message with AppleScript
	osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_MISSING_MAINCLASS}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
	# exit with error
	exit 2
fi
 
 
 
# execute $JAVACMD and do some preparation
############################################
 
# enable drag&drop to the dock icon
export CFProcessPath="$0"
 
# remove Apples ProcessSerialNumber from passthru arguments (#39)
if [[ "$*" == -psn* ]] ; then
	ArgsPassthru=()
else
	ArgsPassthru=("[email protected]")
fi
 
# change to Working Directory based upon Apple/Oracle Plist info
cd "${WorkingDirectory}" || exit 13
stub_logger "[WorkingDirectory] ${WorkingDirectory}"
 
# execute Java and set
# - classpath
# - splash image
# - dock icon
# - app name
# - JVM options / properties (-D)
# - JVM default options (-X)
# - main class
# - main class arguments
# - passthrough arguments from Terminal or Drag'n'Drop to Finder icon
stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" -splash:\"${ResourcesFolder}/${JVMSplashFile}\" -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
exec "${JAVACMD}" \
		-cp "${JVMClassPath}" \
		-splash:"${ResourcesFolder}/${JVMSplashFile}" \
		-Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
		-Xdock:name="${CFBundleName}" \
		${JVMOptionsArr:+"${JVMOptionsArr[@]}" }\
		${JVMDefaultOptions:+$JVMDefaultOptions }\
		"${JVMMainClass}"\
		${MainArgsArr:+ "${MainArgsArr[@]}"}\
		${ArgsPassthru:+ "${ArgsPassthru[@]}"}

[Solved] passwd: Authentication token manipulation error

problem background

The following error is displayed when the root password is changed in the online environment:

[root]# passwd root
Changing password for user root.
passwd: Authentication token manipulation error

Solution

View /etc/passwd, /etc/shadow file properties

[root]# lsattr /etc/shadow
----i----------- /etc/shadow
[root]# lsattr /etc/passwd
----i----------- /etc/passwd

Notes:

  • A: Atime, which tells the system not to modify the last access time to this file.
  • S: Sync, once the application performs a write operation on the file, the system immediately writes the modified result to the disk.
  • a: Append Only, the system only allows appending data after this file, and does not allow any process to overwrite or truncate this file. If a directory has this attribute, the system will only allow files to be created and modified in this directory, not to delete any files.
  • b: Do not update the last access time of the file or directory.
  • c: Compress the file or directory and store it.
  • d: When the dump program is executed, the file or directory will not be backed up by dump.
  • D: Check for errors in the compressed file.
  • i: Immutable, the system does not allow any modification to this file. If the directory has this attribute, any process can only modify the files under the directory, and is not allowed to create and delete files.
  • s: The file is completely deleted and cannot be recovered, because it is deleted from the disk, and then fills the area where the file is located with 0.
  • u: When an application requests to delete the file, the system reserves its data blocks so that the file can be undeleted later to prevent accidental deletion of the file or directory.
  • t: The file system supports tail-merging.
  • X: The contents of the compressed file can be directly accessed.

 

Revoke the i file attributes of /etc/passwd and /etc/shadow

[root]# chattr -i /etc/shadow
[root]# chattr -i /etc/passwd

 

Check the /etc/passwd, /etc/shadow file properties again

[root]# lsattr /etc/shadow
---------------- /etc/shadow
[root]# lsattr /etc/passwd
---------------- /etc/passwd

Then, re-update the user password.

[Solved] xtrabackup: error: xb_load_tablespaces() failed with error code 57

Problem description: Some errors occur when running the xtrabackup backup script on the database

DB_version:mysql8.0.26

Xtrabackup: percona-xtrabackup-8.0.27-19-Linux-x86_64.glibc2.12.tar.gz

[[email protected] scripts]# $xtrDir --defaults-file=$mysql_cnf --user=$mysql_user --password=$mysql_password --socket=$mysql_socket --compress --compress-threads= 2 --backup -- target-dir= $target_dir
xtrabackup: recognized server arguments: --datadir=/home/mysql/db_orch2/data --tmpdir=/home/mysql/db_orch2/tmp --log_bin=/home/mysql/db_orch2/binlog/orch2-bin --log- bin-index=/home/mysql/db_orch2/binlog/orch2-bin.index --server-id= 1330611 --innodb_open_files= 63000 --innodb_data_home_dir=/home/mysql/db_orch2/data --innodb_log_group_home_dir=/home/mysql /db_orch2/data --innodb_log_file_size=8G --innodb_log_files_in_group= 4 --innodb_undo_directory=/home/mysql/db_orch2/ulog --innodb_undo_tablespaces= 3 --innodb_flush_log_at_trx_commit= 2 --innodb_flush_method=O_DIRECT --innodb_io_capacity= 3000--innodb_buffer_pool_size=64G --innodb_log_buffer_size=32M --innodb_max_dirty_pages_pct= 85 --innodb_adaptive_hash_index= 1 --innodb_data_file_path=ibdata1:512M:autoextend --innodb_write_io_threads= 16 --innodb_read_io_threads = 16  
xtrabackup: recognized client arguments --password=* --socket=/home/mysql/db_orch2/mysql.sock --compress --compress-threads= 2 --backup= 1 --target-dir=/home/mysql/backup/ 13306 // 2022-04-06 
/root/percona-xtrabackup/bin/xtrabackup version 8.0 . 27 - 19 based on MySQL server 8.0 .27 Linux (x86_64) (revision id: 50dbc8dadda)
Can ' t locate Data/Dumper.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl / usr/lib64/perl5 /usr/share/perl5 .) at - line 749. 
BEGIN failed--compilation aborted at - line 749 .
 220406  12 : 26 : 14 Connecting to MySQL server host: localhost, user: root, password: set , port: not set , socket : /home/mysql/db_orch2/mysql.sock
Using server version 8.0 . 26 
220406  12 : 26 : 14 Executing LOCK INSTANCE FOR BACKUP...
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /home/mysql/db_orch2/ data
xtrabackup: open files limit requested 0 , set to 1024 
xtrabackup: using the following InnoDB configuration:
xtrabackup: innodb_data_home_dir = /home/mysql/db_orch2/ data
xtrabackup: innodb_data_file_path = ibdata1:512M:autoextend
xtrabackup: innodb_log_group_home_dir = /home/mysql/db_orch2/ data
xtrabackup: innodb_log_files_in_group = 4 
xtrabackup: innodb_log_file_size = 8589934592 
xtrabackup: using O_DIRECT
Number of pools: 1
xtrabackup: initialize_service_handles suceeded
220406  12 : 26 : 14 Connecting to MySQL server host: localhost, user: root, password: set , port: not set , socket: /home/mysql/db_orch2/mysql.sock
xtrabackup: Redo Log Archiving is not set up.
Starting to parse redo log at lsn = 1276785485862 
220406  12 : 26 : 14 >> log scanned up to ( 1276786464962 )
xtrabackup: Generating a list of tablespaces
xtrabackup: Generating a list of tablespaces
Scanning ' ./ ' 
Scanning ' /home/mysql/db_orch2/ulog/ ' 
Completed space ID check of 2 files.
Allocated tablespace ID 2198  for eomaqzy_data/app_source_rela, old maximum was 0 
220406  12 : 26 : 15 >> log scanned up to ( 1276786574060 )
Undo tablespace number 1 was being truncated when mysqld quit.
Cannot recover a truncated undo tablespace in read- only mode
 xtrabackup: error: xb_load_tablespaces() failed with error code 57

 

Check whether there are undo files in the data file directory, clean up the undo files and test the backup again

 

mv undo*.log /tmp

 

 

 

 

 

Error two:

 

 

xtrabackup: Can ' t create/write to file ' /home/mysql/backup/ 13306 / 2022-04-06 /eomaqzy_data/pl02_inv_meter_data.ibd.qp ' ( OS errno 24 - Too many open files) You 
are in / var /spool There are mails in /mail/root

 

 

OS file count unadjusted limit

[[email protected] 13306 ]# ulimit - n
 1024

[[email protected] ~]# grep -i nofile /etc/security/limits.conf
#         - nofile - max number of open file descriptors

[[email protected] ~]# vim /etc/security/limits.conf
 * hard nofile 65535 
* soft nofile 65535

Disconnect and log back in
[[email protected] ~]# ulimit - n
 65535

 

back up again

+ echo =========================Run full backup beginning =================== =======
+ /root/percona-xtrabackup/bin/xtrabackup --defaults-file=/home/mysql/db_orch2/conf/orch2.cnf --user=root --password=XXXXX --socket=/home/mysql/db_orch2/ mysql.sock --compress --compress-threads= 2 --backup --target - dir=/home/mysql/backup/ 13306 / 2022-04-06 + 
echo =========== ============Run full backup 
finished successfully ======================================================================================================================================== There are mails in /mail/root

[Solved] Azure Function Enable Managed Identity and Powershell Funciton Report Error: ERROR: ManagedIdentityCredential authentication failed

Problem Description

Write a Powershell Function, log in to China Azure and get Azure AD User information, but found that [Error] ERROR: ManagedIdentityCredential authentication failed: An unexpected error occured while fetching the AAD Token. Please contact support with this provided Correlation IdStatus: 500 (Internal Server Error).

 

problem analysis

Analyze the cause of the error. This is because there is an error when logging in with Powershell. Considering that you are currently logged in to Azure in China, when you log in with Connect-AzAccount, you want to specify -Environment as AzureChinaCloud.

The PowerShell Function App automatically adds the profile.ps1 file to the root directory  . The default file content is:

# Azure Functions profile.ps1
#
# This profile.ps1 will get executed every "cold start" of your Function App. 
# "cold start" occurs when:
#
# * A Function App starts up for the very first time 
# * A Function App starts up after being de-allocated due to inactivity
#
# You can define helper functions, run commands, or specify environment variables 
# NOTE: any variables defined that are not environment variables will get reset after the first execution

# Authenticate with Azure PowerShell using MSI. 
# Remove this if you are not planning on using MSI or Azure PowerShell. 
if ( $env:MSI_SECRET ) {
    Disable -AzContextAutosave -Scope Process | Out- Null
    Connect -AzAccount- Identity
}

# Uncomment the next line to enable legacy AzureRm alias in Azure PowerShell. 
# Enable-AzureRmAlias

# You can also define functions or aliases that can be referenced in any of your PowerShell functions.
It can be seen that the default Connect-AzAccount -Identity does not specify Environment, so when Function runs, it will connect to Global Azure by default, so ManagedIdentityCredential authentication failed will appear.

PS : If Managed Identity is not enabled, $env:MSI_SECRET is False and the code in profile.ps1 will not be executed.

 

solution

On the Function App page, click App Service Editor, and modify the profile.ps1 file.

use

Connect-AzAccount -Environment AzureChinaCloud -Identity

replace

Connect-AzAccount-Identity

The screenshot of the operation is as follows:

After modification, go back to the Function –> Code + Test page, and the test problem disappears.

using namespace System.Net

# Input bindings are passed in via param block. 
param ( $Request , $TriggerMetadata )

# Write to the Azure Functions log stream. 
Write-Host " PowerShell HTTP trigger function processed a request. " 
Write -Host $env:MSI_SECRET 
# Interact with query parameters or the body of the request. 
$name = $Request .Query.Name
 if ( -not  $name ) {
     $name = $Request .Body.Name
}

$body = " This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response. "

if ( $name ) {
     $body = " Hello, $name. This HTTP triggered function executed successfully. "
}
# login in to azure china 
Connect-AzAccount -Environment AzureChinaCloud - identity
 # get User information 
Get-AzADUser -First 2 -Select 'City' - AppendSelected

# Associate values ​​to output bindings by calling 'Push-OutputBinding'.Push 
-OutputBinding -Name Response -Value ([HttpResponseContext]@ {
    StatusCode = [HttpStatusCode]:: OK
    Body = $body 
})

Note: In order for Connect-AzAccount to run successfully, you need to add ‘Az’ = ‘7.*’ in requirements.psd1, so that the instance of Function App installs the Az module. Of course, if you need other Powershell modules in Function, you can add them here.

# This file enables modules to be automatically managed by the Functions service. 
# See https://aka.ms/functionsmanageddependency for additional information.
#
@ {
     # For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'. 
    # To use the Az module in your function app, please uncomment the line below. 
    'Az' = '7. * '
}

[Solved] Application_Error not firing when customerrors = “On”

Question:

I have code in the global.asax file’s Application_Error event which executes when an error occurs and emails details of the error to myself.

void Application_Error(object sender, EventArgs e)
{
    var error = Server.GetLastError();

    if (error.Message != "Not Found")
    {
        // Send email here...
    }

}

This works fine when I’m running it in Visual Studio, however when I publish to our live server the Application_Error event does not fire.

After some testing I can get the Application_Error firing when I set customErrors="Off", however setting it back to customErrors="On" stops the event from firing again.

Can anyone suggest why Application_Error would not be firing when customErrors are enabled in the web.config?

 

Solution 1:

UPDATE
Since this answer does provide a solution, I will not edit it, but I have found a much cleaner way of solving this problem. See my other answer for details…

Original Answer:
I figured out why the Application_Error() method is not being invoked…

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute()); // this line is the culprit
    }
...
}

By default (when a new project is generated), an MVC application has some logic in the Global.asax.cs file. This logic is used for mapping routes and registering filters. By default, it only registers one filter: a HandleErrorAttribute filter. When customErrors are on (or through remote requests when it is set to RemoteOnly), the HandleErrorAttribute tells MVC to look for an Error view and it never calls the Application_Error() method. I couldn’t find documentation of this but it is explained in this answer on programmers.stackexchange.com.

To get the ApplicationError() method called for every unhandled exception, simple remove the line which registers the HandleErrorAttribute filter.

Now the problem is: How to configure the customErrors to get what you want…

The customErrors section defaults to redirectMode="ResponseRedirect". You can specify the defaultRedirect attribute to be a MVC route too. I created an ErrorController which was very simple and changed my web.config to look like this…

web.config

<customErrors mode="RemoteOnly" redirectMode="ResponseRedirect" defaultRedirect="~/Error">
  <error statusCode="404" redirect="~/Error/PageNotFound" />
</customErrors>

The problem with this solution is that it does a 302 redirect to your error URLs and then those pages respond with a 200 status code. This leads to Google indexing the error pages which is bad. It also isn’t very conformant to the HTTP spec. What I wanted to do was not redirect, and overrite the original response with my custom error views.

I tried to change redirectMode="ResponseRewrite". Unfortunately, this option does not support MVC routes, only static HTML pages or ASPX. I tried to use an static HTML page at first but the response code was still 200 but, at least it didn’t redirect. I then got an idea from this answer

I decided to give up on MVC for error handling. I created an Error.aspx and a PageNotFound.aspx. These pages were very simple but they had one piece of magic…

<script type="text/C#" runat="server">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        Response.StatusCode = (int) System.Net.HttpStatusCode.InternalServerError;
    }
</script>

This block tells the page to be served with the correct status code. Of course, on the PageNotFound.aspx page, I used HttpStatusCode.NotFound instead. I changed my web.config to look like this…

<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx">
  <error statusCode="404" redirect="~/PageNotFound.aspx" />
</customErrors>

It all worked perfectly!

Summary:

  • Remove the line: filters.Add(new HandleErrorAttribute());
  • Use Application_Error() method to log exceptions
  • Use customErrors with a ResponseRewrite, pointing at ASPX pages
  • Make the ASPX pages responsible for their own response status codes

There are a couple downsides I have noticed with this solution.

  • The ASPX pages can’t share any markup with Razor templates, I had to rewrite our website’s standard header and footer markup for a consistent look and feel.
  • The *.aspx pages can be accessed directly by hitting their URLs

There are work-arounds for these problems but I wasn’t concerned enough by them to do any extra work.

I hope this helps everyone!

 

Solution 2:

I solved this by creating an ExceptionFilter and logging the error there instead of Application_Error. All you need to do is add a call to in in RegisterGlobalFilters

log4netExceptionFilter.cs

using System
using System.Web.Mvc;

public class log4netExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        Exception ex = context.Exception;
        if (!(ex is HttpException)) //ignore "file not found"
        {
            //Log error here
        }
    }
}

Global.asax.cs

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new log4netExceptionFilter()); //must be before HandleErrorAttribute
    filters.Add(new HandleErrorAttribute());
}

[Solved] MAVEN-COMPILER-PLUGIN Compile Error: FATAL ERROR: UNABLE TO FIND PACKAGE JAVA.LANG IN CLASSPATH OR BOOTCLASSPATH

When I used maven-compiler-plugin to add some environment variables, the codes is as following below. It was found that in the bootclasspath, two variables were separated by a semicolon, so an error was reported, as shown in the following figure.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.0</version>
    <configuration>
        <!-- 1.8 and 1.7 don't matter -->
        <source>1.7</source>
        <target>1.7</target>
        <compilerArguments>
            <!-- Do not write, only rt.jar by default -->
            <bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar</bootclasspath>
        </compilerArguments>
    </configuration>
</plugin>

 

 

 

Solution

The replacement code is shown below, using ${path.separator}the semicolon instead. Because under windowsand linuxunder, need to use different delimiters. windowsUse a semicolon, linuxuse a colon.

 

<bootclasspath>${java.home}/lib/rt.jar${path.separator}${java.home}/lib/jce.jar</bootclasspath>

[Solved] Json.Net Error: Error getting value from ‘ScopeId’ on ‘System.Net.IPAddress’

The IPAddress class is not very friendly to serialization, as you’ve seen. Not only will it throw a SocketException if you try to access the ScopeID field for an IPv4 address, but it will also throw if you try to access the Address field directly for an IPv6 address.

To get around the exceptions, you will need a custom JsonConverter. A converter allows you to tell Json.Net exactly how you’d like it to serialize and/or deserialize a particular type of object. For an IPAddress, it seems the easiest way to get the data that satisfies everyone is simply to convert it to its string representation and back. We can do that in the converter. Here is how I would write it:

class IPAddressConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IPAddress));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(value.ToString());
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return IPAddress.Parse((string)reader.Value);
    }
}
Pretty straightforward, as these things go. But, this is not the end of the story. If you need to go round-trip with your IPEndPoint, then you will need a converter for it as well. Why? Because IPEndPoint does not contain a default constructor, so Json.Net will not know how to instantiate it. Fortunately, this converter is not difficult to write either:
class IPEndPointConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IPEndPoint));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        IPEndPoint ep = (IPEndPoint)value;
        JObject jo = new JObject();
        jo.Add("Address", JToken.FromObject(ep.Address, serializer));
        jo.Add("Port", ep.Port);
        jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        IPAddress address = jo["Address"].ToObject<IPAddress>(serializer);
        int port = (int)jo["Port"];
        return new IPEndPoint(address, port);
    }
}
So, now that we have the converters, how do we use them? Here is a simple example program that demonstrates. It first creates a couple of endpoints, serializes them to JSON using the custom converters, then immediately deserializes the JSON back into endpoints again using the same converters.
public class Program
{
    static void Main(string[] args)
    {
        var endpoints = new IPEndPoint[]
        {
            new IPEndPoint(IPAddress.Parse("8.8.4.4"), 53),
            new IPEndPoint(IPAddress.Parse("2001:db8::ff00:42:8329"), 81)
        };

        var settings = new JsonSerializerSettings();
        settings.Converters.Add(new IPAddressConverter());
        settings.Converters.Add(new IPEndPointConverter());
        settings.Formatting = Formatting.Indented;

        string json = JsonConvert.SerializeObject(endpoints, settings);
        Console.WriteLine(json);

        var endpoints2 = JsonConvert.DeserializeObject<IPEndPoint[]>(json, settings);

        foreach (IPEndPoint ep in endpoints2)
        {
            Console.WriteLine();
            Console.WriteLine("AddressFamily: " + ep.AddressFamily);
            Console.WriteLine("Address: " + ep.Address);
            Console.WriteLine("Port: " + ep.Port);
        }
    }
}

Here is the output:

[
  {
    "Address": "8.8.4.4",
    "Port": 53
  },
  {
    "Address": "2001:db8::ff00:42:8329",
    "Port": 81
  }
]

AddressFamily: InterNetwork
Address: 8.8.4.4
Port: 53

AddressFamily: InterNetworkV6
Address: 2001:db8::ff00:42:8329
Port: 81

Fiddle: https://dotnetfiddle.net/tK7NKY

  • Code of WriteJson can be simplified using JObject too. 
  • Performance impact of WriteJson and ReadJson can be improved by using the writer and reader objects, avoiding JObject allocation. I have submitted an edit to this very useful answer.